Manual Inicio Android (1).pdf

179
Manual Inicio Android Pasos básicos para crear una aplicación Android con ejemplos. El presente documento trata de introducir al alumno al desarrollo de aplicaciones Android, guiándolo en el desarrollo de una aplicación con varios ejemplos básicos que abarca en gran medida los conceptos básicos en el desarrollo de aplicaciones Android utilizando el ADT (Android Developer Tools) de Eclipse. 2014 NELSON CROZBY PADILLA ALVAREZ UTM 12/02/2014

Transcript of Manual Inicio Android (1).pdf

Page 1: Manual Inicio Android (1).pdf

 

 

   

Manual  Inicio  Android  Pasos  básicos  para  crear  una  aplicación  Android    con  ejemplos.    El  presente  documento  trata  de  introducir  al  alumno  al  desarrollo  de  aplicaciones  Android,  guiándolo  en  el  desarrollo  de  una  aplicación  con  varios  ejemplos  básicos  que  abarca  en  gran  medida  los  conceptos  básicos  en  el  desarrollo  de  aplicaciones  Android  utilizando  el  ADT  (Android  Developer  Tools)  de  Eclipse.    

2014  

NELSON  CROZBY  PADILLA  ALVAREZ  UTM  

12/02/2014  

Page 2: Manual Inicio Android (1).pdf

 

  1  

Tabla  de  contenido  ¿Qué  es  Android?  ..................................................................................................................................  5  El  sistema  operativo  Android  .......................................................................................................................  5  Task  (tarea)  ..................................................................................................................................................  5  Componentes  de  la  plataforma  Android  ......................................................................................................  5  Google  Play  ..................................................................................................................................................  7  

Android  Development  Tools  .............................................................................................................  7  Android  SDK  .................................................................................................................................................  7  Android  debug  bridge  (adb)  .........................................................................................................................  7  Android  Developer  Tools  y  Android  Studio  ..................................................................................................  7  Dalvik  Virtual  Machine  .................................................................................................................................  8  Android  Runtime  ..........................................................................................................................................  8  Como  desarrollar  aplicaciones  Android  .......................................................................................................  8  Proceso  de  conversión  desde  código  fuente  hasta  una  aplicación  Android  ................................................  9  

Seguridad  y  permisos  ..........................................................................................................................  9  Concepto  de  seguridad  en  Android  .............................................................................................................  9  Concepto  de  permiso  en  Android  ................................................................................................................  9  

Instalación  ...........................................................................................................................................  10  Consideraciones  previas  y  de  instalación  ...................................................................................................  10  Preparar  IDE  ...............................................................................................................................................  11  

Emulador  de  dispositivo  Android  y  Dispositivo  Virtual  Android  (Android  Virtual  Devices,  AVD)  ......................................................................................................................................  13  Emulador  Android  y  Android  Virtual  Device  ..............................................................................................  13  Atajos  para  el  emulador  de  dispositivos  Android  ......................................................................................  14  Google  vs.  Android  AVD  .............................................................................................................................  15  Optimización  de  Velocidad  ........................................................................................................................  15  Emulador  Intel  ............................................................................................................................................  16  Emulador  Alternativo  .................................................................................................................................  17  

Ejercicio:  Crear  e  iniciar  Android  Virtual  Device  ...................................................................  17  Target  (objetivo)  ........................................................................................................................................  17  Crear  el  AVD  ...............................................................................................................................................  17  Iniciar  tu  AVD  .............................................................................................................................................  19  

Ejercicio:  Crear  aplicación  Android  en  Eclipse  .......................................................................  20  Asistente  de  proyectos  Android  .................................................................................................................  20  Crear  proyecto  Android  .............................................................................................................................  20  

Ejercicio:  Inicie  la  aplicación  Android  generada  ....................................................................  25  Iniciar  AVD  ..................................................................................................................................................  25  Inicicar  la  aplicación  ...................................................................................................................................  26  

Page 3: Manual Inicio Android (1).pdf

 

  2  

Integración  de  ADT  dentro  de  Eclipse  ........................................................................................  27  Integración  de  Android  dentro  de  la  perspectiva  Java  ...............................................................................  27  Asistentes  de  Android  ................................................................................................................................  27  

Perspectiva  DDMS  .............................................................................................................................  28  Perspectiva  Android  ...................................................................................................................................  28  File  Explorer  ...............................................................................................................................................  29  

Partes  de  una  aplicación  Android  ................................................................................................  29  Aplicación  Android  .....................................................................................................................................  29  Componentes  de  software  Android  ...........................................................................................................  29  Contexto  .....................................................................................................................................................  30  

Vistazo  a  los  componentes  de  una  aplicación  Android  ........................................................  30  Activity  (Actividad)  .....................................................................................................................................  30  BroadcastReceiver  .....................................................................................................................................  30  Service  (Servicio)  ........................................................................................................................................  30  ContentProvider  .........................................................................................................................................  31  

Componentes  base  en  las  interfaces  de  usuario  en  Android  ..............................................  31  Acitivity  (Actividad)  ....................................................................................................................................  31  Fragments  (Fragmentos)  ............................................................................................................................  31  Views  y  control  de  distribución  ..................................................................................................................  32  Diseños  específicos  de  configuración  de  dispositivos  ................................................................................  32  

Otros  elementos  importantes  de  Android  ................................................................................  32  Pantalla  principal  y  la  pantalla  de  bloqueo  de  widgets  ..............................................................................  32  Live  Wallpapers  ..........................................................................................................................................  33  

El  Android  Manifest  ..........................................................................................................................  33  La  configuración  de  la  aplicación  para  Android  .........................................................................................  33  Declarar  los  componentes  en  el  archivo  de  manifiesto  .............................................................................  33  Permisos  .....................................................................................................................................................  33  Ejemplo  del  archivo  AndroidManifes.xml  ..................................................................................................  33  

El  manifiesto  de  Android  ................................................................................................................  34  Versión  y  paquete  ......................................................................................................................................  34  

Ciclo  de  vida  de  una  Activity  ..........................................................................................................  36  Entendiendo  el  flujo  del  ciclo  de  vida  ........................................................................................................  36  

Creación  y  manejo  de  Base  de  Datos  ...........................................................................................  37  Crear  la  BD  con  SQLite  en  Navicat.  .............................................................................................................  37  Cargar  la  base  de  datos  en  el  proyecto  de  Android  ...................................................................................  42  Cargar  la  base  de  datos  en  la  aplicación  para  poder  usarla  .......................................................................  43  Creación  de  la  Base  de  Datos  con  código  desde  la  aplicación  ...................................................................  50  Manejo  de  SQLite  en  Android  ....................................................................................................................  54  

Page 4: Manual Inicio Android (1).pdf

 

  3  

SQLiteOpenHelper  .....................................................................................................................................  54  SQLDatabase  y  Cursor  ................................................................................................................................  54  

Creando  un  Navigation  Drawer  ....................................................................................................  58  Abrir  y  Cerrar  menú  desde  un  ícono.  .........................................................................................................  70  Asignar  acción  a  la  pulsación  de  un  Item  del  menú  de  navegación  ...........................................................  72  

Interactuar  con  una  Base  de  Datos  ..............................................................................................  79  Agregar  recursos  a  la  aplicación  .................................................................................................................  79  Diseño  de  layouts  .......................................................................................................................................  81  Agregar  clases  para  manejo  de  interacción  con  la  base  de  datos  ..............................................................  82  

Trazar  una  ruta  ..................................................................................................................................  92  Utils.java  ................................................................................................................................................  96  ConnectionDetecter.java  ........................................................................................................................  98  GMapsDirection.java  ..............................................................................................................................  99  Creación  de  elementos  visuales  ...........................................................................................................  105  

Adapters  .............................................................................................................................................  114  Entender  el  comportamiento  interno  de  un  Android  Adapter  ................................................................  114  

Mapas  en  Android  (Google  Maps  Android  API  v2)  ...............................................................  115  Pasos  para  instalar  y/o  configurar  la  API  de  Google  Maps  Android.  ........................................................  115  Pasos  para  construir  una  aplicación  básica  usando  la  API  de  Google  Maps  ............................................  125  Interactuando  con  el  Mapa  (pasar  coordenadas)  ....................................................................................  127  

Localización  geográfica  en  Android  ..........................................................................................  128  ¿Qué  mecanismos  de  localización  tenemos  disponibles?  .......................................................................  128  ¿Qué  proveedor  de  localización  es  mejor  para  mi  aplicación?  ................................................................  129  ¿Está  disponible  y  activado  un  proveedor  determinado?  ........................................................................  130  El  GPS  ya  está  activado,  ¿y  ahora  qué?  ....................................................................................................  131  

AsyncTask  ..........................................................................................................................................  139  Tipos  genéricos  ........................................................................................................................................  139  Etapas  del  ASyncTask  ...............................................................................................................................  139  Las  reglas  del  juego  ..................................................................................................................................  140  

Navegación  .........................................................................................................................................  140  Navegación  con  Back  y  Up  .......................................................................................................................  140  Up  vs.  Back  ...............................................................................................................................................  141  Navegación  dentro  de  su  aplicación  ........................................................................................................  142  Navegando  dentro  de  la  aplicación  vía  Widgets  en  la  pantalla  Home  y  las  Notificaciones.  ....................  145  Notificaciones  Indirectas  ..........................................................................................................................  146  Notificaciones  pop-­‐up  ..............................................................................................................................  147  Navegando  entre  aplicaciones  .................................................................................................................  148  

Estilos  en  Android  ...........................................................................................................................  152  

Page 5: Manual Inicio Android (1).pdf

 

  4  

Dispositivos  y  Pantallas  ............................................................................................................................  152  Temas  .......................................................................................................................................................  153  Retroalimentación  al  Toque  .....................................................................................................................  155  

Estados  .................................................................................................................................................  156  Comunicación  ...........................................................................................................................................  156  

Límites  ..................................................................................................................................................  157  Métricas  y  Rejillas  ....................................................................................................................................  157  48dp  Rhythm  ............................................................................................................................................  158  

¿Por    qué  48dp?  ....................................................................................................................................  158  Cuidado  con  el  hueco  ...........................................................................................................................  159  

Tipografía  .................................................................................................................................................  160  Colores  de  tipo  predeterminado  ...........................................................................................................  161  Escala  Tipográfica  ................................................................................................................................  161  

Color  .........................................................................................................................................................  161  Paleta  ...................................................................................................................................................  162  

Iconografía  ...............................................................................................................................................  162  Lanzador  ...............................................................................................................................................  163  Action  Bar  .............................................................................................................................................  165  Iconos  pequeños/contextuales  .............................................................................................................  166  Iconos  de  notificación  ...........................................................................................................................  167  Consejos  de  Diseño  ...............................................................................................................................  168  

Su  imagen  de  marca  .................................................................................................................................  171  Color  .....................................................................................................................................................  171  Logo  ......................................................................................................................................................  172  Iconos  ...................................................................................................................................................  173  

Estilos  de  Escritura.  ..................................................................................................................................  174  La  voz  de  Android.  ................................................................................................................................  174  

 

   

Page 6: Manual Inicio Android (1).pdf

 

  5  

¿Qué  es  Android?  El  sistema  operativo  Android  

Android  es  un  sistema  operativo  basado  en  el  kernel  de  Linux.  El  proyecto  responsable  del  desarrollo  del  sistema   Android   es   llamado   Android   Open   Source   Project   (AOSP)   y   es   principalmente   liderado   por  Google.  

El   sistema   operativo   Android   soporta   procesamiento   en   background;   proporciona   una   librería   de  interfaces  de  usuario  enriquecida,  soporta  gráficos  2D  y  3D  usando  el  estándar  OpenGL-­‐ES  y  garantiza  acceso  a  los  archivos  del  sistema  así  como  la  base  de  datos  embebida  SQLite  

Una   aplicación   Android   típicamente   consiste   de   diferentes   componentes   visuales   y   no   visuales   y   se  pueden  volver  a  utilizar  componentes  de  otras  aplicaciones.  

Task  (tarea)  

La   reutilización   de   los   componentes   de   otras   aplicaciones   nos   lleva   al   concepto   de   task   (tarea)   en  Android.   Una   aplicación   puede   acceder   a   otros   componentes   de   Android   para   lograr   una   task.   Por  ejemplo,  a  partir  de  un  componente  de  nuestra  aplicación,  puede  desencadenar  otro  componente  en  el  sistema  Android,  el  cual  gestiona  sus  fotos,  aunque  este  componente  no  es  parte  de  su  aplicación.  En  este  componente  se  selecciona  una  foto  y  volver  a  la  aplicación  para  utilizar  la  foto  seleccionada.  

Tal  flujo  de  eventos  se  representa  en  el  siguiente  gráfico.  

 

   

 

 Componentes  de  la  plataforma  Android  

1.-­‐  Usuario  dispara  “Recoger  foto”  vía  botón  

2.-­‐  inicia  galería  

3.-­‐  Usuario  selecciona  una  foto  

4.-­‐  Regresa  la  foto  seleccionada  

Page 7: Manual Inicio Android (1).pdf

 

  6  

El  sistema  Android  es  una  completa  pila  de  software,  que  suele  estar  dividido  en  las  cuatro  áreas  como  se  muestra  en  el  siguiente  gráfico.  

 

Los  niveles  pueden  ser  descritos  como:  

• Applications  (Aplicaciones)  -­‐  El  Proyecto  Open  Source  Android  contiene  varias  aplicaciones  por  defecto,  como  el  Navegador,  Cámara,  Galería,  Música,  teléfono  y  mucho  más.  

• Application  framework  (Marco  de  aplicación)  -­‐  API  que  permite  la  interacción  de  alto  nivel  con  el  sistema  Android  desde  las  aplicaciones  de  Android.  

• Libraries  and  runtime  (Librerías  y  tiempo  de  ejecución)  -­‐  Bibliotecas  para  Application  framework    con   muchas   funciones   comunes   (renderizado   gráfico,   almacenamiento   de   datos,   navegación  web,  etc),  así  como  el  runtime  Dalvik  y  las  bibliotecas  fundamentales  de  Java  para  la  ejecución  de  aplicaciones  Android.  

• Kernel  Linux  -­‐  capa  de  la  Comunicación  para  el  hardware  subyacente.  

El   kernel   de   Linux,   las   bibliotecas   y   el   runtime   se   encapsulan   en   el   Application   framework.   El  desarrollador  de  aplicaciones  Android  normalmente  trabaja  con  las  dos  capas  en  la  parte  superior  para  crear  nuevas  aplicaciones  de  Android.  

 

Page 8: Manual Inicio Android (1).pdf

 

  7  

Google  Play  

Google  ofrece  el  servicio  de  Google  Play,  un  mercado  en  el  que  los  programadores  pueden  ofrecer  sus  aplicaciones  Android  para  los  usuarios  de  Android.  Los  clientes  utilizan  la  aplicación  Google  Play  lo  que  les  permite  comprar  e  instalar  las  aplicaciones  del  servicio  Google  Play.  

Google  Play  también  ofrece  un  servicio  de  actualización.  Si  un  programador  carga  una  nueva  versión  de  su   aplicación   a   Google   Play,   este   servicio   avisa   a   los   usuarios   existentes   que   hay   una   actualización  disponible  y  permite  que  se  instalen  la  actualización.  

Google  Play  permite  el  acceso  a  los  servicios  y  bibliotecas  para  los  programadores  de  aplicaciones  para  Android,   también.   Por   ejemplo,   se   ofrece   un   servicio   para   usar   y   mostrar   Google   Maps   y   otro   para  sincronizar  el   estado  de   la   aplicación  entre   las  diferentes   instalaciones  Android.   La  provisión  de  estos  servicios  a  través  de  Google  Play  tiene  la  ventaja  de  que  están  disponibles  para  las  versiones  de  Android  más  viejas  y  pueden  ser  actualizados  por  Google  sin  la  necesidad  de  una  actualización  de  la  versión  de  Android  en  el  teléfono.  

Android  Development  Tools  Android  SDK  

El  Kit  de  desarrollo  de  software  Android  (Android  SDK)  contiene  las  herramientas  necesarias  para  crear,  compilar   y   empaquetar   aplicaciones   de   Android.   La  mayoría   de   estas   herramientas   están   basadas   en  línea  de  comandos.  La  principal  manera  de  desarrollar  aplicaciones  de  Android  se  basa  en  el  lenguaje  de  programación  Java.  

Android  debug  bridge  (adb)  

El   SDK   de   Android   contiene   el   Android   debug   bridge   (adb),   que   es   una   herramienta   que   le   permite  conectarse   a   un   dispositivo   Android   virtual   o   real,   con   la   finalidad   de   gestionar   el   dispositivo   o   la  depuración  de  la  aplicación.  

Android  Developer  Tools  y  Android  Studio  

Google  proporciona  dos  entornos  de  desarrollo  integrado  (IDE)  para  desarrollar  nuevas  aplicaciones.  

Las  herramientas  de  desarrollo  de  Android  (ADT)  se  basan  en  el  IDE  de  Eclipse.  ADT  es  un  conjunto  de  componentes  (plug-­‐ins),  que  amplían  el  IDE  Eclipse  con  capacidades  de  desarrollo  de  Android.  

Google  también  es  compatible  con  un  IDE  llamado  Android  Estudio  para  la  creación  de  aplicaciones  de  Android.  Este  IDE  se  basa  en  la  IDE  IntelliJ.  

Ambas   herramientas   proporcionan   editores   especializados   para   archivos   específicos   Android.   La  mayoría  de  los  archivos  de  configuración  de  Android  están  basados  en  XML.  En  este  caso,  estos  editores  

Page 9: Manual Inicio Android (1).pdf

 

  8  

permiten  alternar  entre  la  representación  XML  del  archivo  y  una  interfaz  de  usuario  estructurado  para  introducir  los  datos.  

Ambos   IDEs   contienen   toda   la   funcionalidad   necesaria   para   crear,   compilar,   depurar   y   desplegar  aplicaciones  de  Android.  También  permiten  a  los  desarrolladores  crear  e  iniciar  los  dispositivos  Android  virtuales  para  pruebas.  

Dalvik  Virtual  Machine  

El  sistema  Android  utiliza  una  máquina  virtual  especial,  es  decir,  El  sistema  Android  utiliza  una  máquina  virtual  especial,  es  decir,  la  máquina  virtual  de  Dalvik  (Dalvik)  para  ejecutar  aplicaciones  basadas  en  Java.  Dalvik  utiliza  un  formato  de  bytecode  a  medida  que  es  diferente  del  bytecode  de  Java.    

Por   lo  tanto  no  se  puede  ejecutar  archivos  de  clase  Java  en  Android  directamente,  sino  que  necesitan  ser  convertidos  en  el  formato  de  bytecode  de  Dalvik.    

Dalvik   funciona   de   forma   similar   a   la   máquina   virtual   de   Java   en   cuanto   a   la   optimización   de  aplicaciones.  Optimiza   la  aplicación  en  tiempo  de  ejecución.  Esto  se  conoce  como  Just   In  Time  (JIT).  Si  una  parte  de  la  aplicación  se  llama  con  frecuencia,  Dalvik  optimizará  esta  parte  del  código  y  lo  compila  a  código  máquina  que  ejecuta  mucho  más  rápido.    

Android  Runtime  

Aplicaciones  de  Android  están  escritas  principalmente  en  el  lenguaje  de  programación  Java.  

Con  Android  4.4,  Google  presentó  el  Android  Runtime   (ART)   como  un   runtime  opcional   para  Android  4.4.  Se  espera  que  las  versiones  posteriores  4.4  usarán  ART  como  runtime  predeterminado.  

ART   utiliza   Ahead   Of   Time   compilation.   Durante   el   despliegue   de   una   aplicación   en   un   dispositivo  Android,  el  código  de  la  aplicación  es  traducida  a  código  máquina.  Esto  da  lugar  a  aprox.  30%  de  código  de  compilación  más  grande,  pero  permite  una  ejecución  más  rápida  desde  el  principio  de  la  aplicación.  

Recordemos  que,  para  efectos  de  este  curso  estaremos  usando  Android  4.0  (API  14),  esto  es  sólo  para  información.  

 

Como  desarrollar  aplicaciones  Android  

Durante  el  desarrollo  el  desarrollador  crea  los  archivos  de  configuración  específicos  para  Android  y  escribe  la  lógica  de  la  aplicación  en  el  lenguaje  de  programación  Java.  

 

Las  herramientas  ADT  o  el  Studio  Android  convierten  esos  archivos  de  la  aplicación  de  forma  transparente  para  el  usuario  en  una  aplicación  Android.  Cuando  los  desarrolladores  inician  el  despliegue  en  su  IDE,  toda  la  aplicación  Android  es  compilada,  empaquetada,  desplegada  e  iniciada.  

Page 10: Manual Inicio Android (1).pdf

 

  9  

Proceso  de  conversión  desde  código  fuente  hasta  una  aplicación  Android  

Los  archivos  de  código  fuente  de  Java  son  convertidos  en  archivos  de  clases  de  Java  por  el  compilador  Java.  

El   SDK   de   Android   contiene   una   herramienta   llamada  dx   que   convierte   archivos   de   clase   Java   en   un  archivo   .dex   (Dalvik   ejecutable).   Todos   los   archivos   de   clase   de   la   aplicación   se   colocan   en   el   archivo  .dex.   Durante   este   proceso   de   conversión   la   información   redundante   en   los   archivos   de   clase   serán  optimizados  en  el  archivo  .dex.  

Por  ejemplo,   si   la  misma  String   se  encuentra  en  archivos  de  clase  diferentes,  el   archivo   .dex   contiene  sólo  una  referencia  a  esta  String.  

Estos   archivos   .dex   son   por   lo   tanto   mucho   más   pequeño   en   tamaño   que   los   archivos   de   clases  correspondientes.  

El  archivo  de   .dex  y   los   recursos  de  un  proyecto  Android,  esto  es,   las   imágenes  y   los  archivos  XML,  se  empaquetan   en   un   archivo   .apk   (Android   Package).   El   programa   aapt   (Android   Asset   Packaging   Tool)  realiza  este  paso.  

El  archivo   .apk   resultante  contiene  todos   los  datos  necesarios  para  ejecutar   la  aplicación  Android  y  se  puede  implementar  en  un  dispositivo  Android  a  través  de  la  herramienta  adb.  

Seguridad  y  permisos  Concepto  de  seguridad  en  Android  

El  sistema  Android  instala  cada  aplicación  Android  con  un  único  usuario  y  ID  de  grupo.  Cada  archivo  de  aplicación  es  privado  para  este  usuario  generado,  esto  es,  otras  aplicaciones  no  pueden  acceder  a  estos  archivos.  Además,  cada  aplicación  Android  se  inicia  en  su  propio  proceso.  

Por   lo   tanto   por   medio   del   kernel   de   Linux   subyacente,   cada   aplicación   Android   se   aísla   de   otras  aplicaciones  en  ejecución.  

Si   se   deben   compartir   los   datos,   la   aplicación   debe   hacer   esto   de   manera   explícita   a   través   de   un  componente   de   Android   que   se   encarga   de   la   distribución   de   los   datos,   por   ejemplo,   a   través   de   un  servicio  o  de  un  proveedor  de  contenido.  

Concepto  de  permiso  en  Android  

Android   contiene   un   sistema   de   permisos   y   predefine   permisos   para   ciertas   tareas.   Cada   aplicación  puede   solicitar   permisos   necesarios,   así   como   definir   nuevos   permisos.   Por   ejemplo,   una   aplicación  puede  declarar  que  requiere  acceso  a  Internet.  

Page 11: Manual Inicio Android (1).pdf

 

  10  

Los  permisos  tienen  diferentes  niveles.  Algunos  permisos  se  conceden  automáticamente  por  el  sistema  Android,  algunos  serán  rechazados  automáticamente.  En  la  mayoría  de  los  casos  los  permisos  solicitados  se   presentan   al   usuario   antes   de   instalar   la   aplicación.   El   usuario   tiene   que   decidir   si   estos   permisos  serán  otorgados  a  la  aplicación.  

Si   el   usuario   deniega   una   autorización   necesaria,   la   aplicación   relacionada   no   se   puede   instalar.   La  comprobación   de   la   autorización   sólo   se   realiza   durante   la   instalación,   los   permisos   no   pueden   ser  negados  u  otorgados  después  de  la  instalación.  

Una   aplicación   Android   declara   los   permisos   necesarios   en   su   archivo   de   configuración  AndroidManifest.xml.  También  puede  definir  los  permisos  adicionales  que  puede  utilizar  para  restringir  el  acceso  a  determinados  componentes.  

Nota  

No  todos   los  usuarios  presten  atención  a   los  permisos  requeridos  durante   la   instalación.  Sin  embargo,  algunos  usuarios  hacen  y  escriben  comentarios  negativos  en  Google  Play   si   creen  que   la  aplicación  es  demasiado  invasiva.  

Instalación  Consideraciones  previas  y  de  instalación  

1. Para  los  fines  de  este  curso  se  considera  que  se  debe  de  tener  instalado  java  con  la  versión  jdk1.7.0_51,   en   caso   de   no   tenerlo   instalado   ir   al   siguiente   enlace  http://www.oracle.com/technetwork/java/javase/downloads/jdk7-­‐downloads-­‐1880260.html  y  escoger  la  opción  que  más  se  apegue  a  su  sistema.  

2. Verificar   tener   instalado   el   ADT   (Android  Developer   Tool),   que   es   la   herramienta   (IDE)   de  desarrollo  basada  en  Eclipse  que  nos  servirá  para  el  desarrollo  de  nuestra  aplicación,  en  este  punto  también  es  bueno  verificar  que  se  tenga  instalado  el  SDK  de  Android.  En  caso  de  no  tenerla  instalado  nada  de  esto,    esta  es  la  url  que  nos  lleva  a  la  página  de  descarga  oficial  del  ADT  http://developer.android.com/sdk/index.html.  a. En  esta  página  hacer  click  en  el  botón  que  se  muestra  en  la  Imagen  1.  

 

Imagen  1  

b. Aceptar   los   términos  y/o  condiciones  además  de  escoger   la  versión  de  32-­‐bit  o  de  64-­‐bit,  como  se  muestra  en  la  Imagen  2  esto  se  define  basándose  en  la  versión  de  java  que  

Page 12: Manual Inicio Android (1).pdf

 

  11  

tengan  instalado  en  su  sistema.  Es  importante  que  escoger  bien  porque  si  no  coinciden  las  versiones  del  jdk  con  el  ADT  no  se  podrá  ni  instalar.  

 

Imagen  2  

c. Ahora   hacer   click   en   el   botón   mostrado   en   la   Imagen   3,   y   esperar   a   descargar   para  instalarlo  

 

Imagen  3  

Preparar  IDE    

1. Para   consideraciones   de   este   manual   se   trabajará   con   la   versión   de   Android   4.0   “Ice   Cream  Sandwich”  (API  14).  

2. Lo  primero  será  ejecutar  la  aplicación  ADT  (Imagen  4).  

 

Imagen  4  

Page 13: Manual Inicio Android (1).pdf

 

  12  

3. Ya  en  marcha  podremos  comprobar  si  tenemos  instalado  el  SDK  adecuado  haciendo  click  en  la  herramienta   Android   SDK   Manager   que   se   puede   ejecutar   haciendo   click   en   el   ícono   de   la  Imagen  5.  

 

Imagen  5  

4. La   ventana   mostrada   en   la   Imagen   6   nos   muestra   todos   los   SDK´s   existentes   y   algunas  herramientas  disponibles,  pero  lo  que  nos  interesa  es  lo  que  está  encerrado  en  el  cuadro  rojo,  hay  dos  opciones  una  que  ya  esté  instalado  el  SDK  que  ocupamos  (y  diga  “Installed”),  y  la  otra  es  que   aún   no   lo   esté   que   es   el   caso   que   muy   probablemente   tengamos   por   ser   de   reciente  instalación,  para  tal  caso  debemos  de  marcar  las  casillas  de  los  checkboxes  en  las  opciones  SDK  Platform,  ARM  EABI  v7a  System  Image  y  Google  APIs,  seleccionadas  estas  opciones  se  procede  a  seleccionar  el  botón  Install  que  ahora  debe  de  decir  Install  2  packages…,    

 

Imagen  6  

 

Page 14: Manual Inicio Android (1).pdf

 

  13  

a. Aparecerá  en  este  momento  una  ventana  que  nos  pide  que  aceptemos  las  condiciones  de   uso   de   los   paquetes   a   instalar   y   seleccionamos  Accept   All,   y   luego   click   al   botón  Install,  como  se  muestra  en  la  Imagen  7    

 

 

Imagen  7  

b. Esperamos  un  tiempo  mientras  descarga  el  sdk  de  internet  y  se  instala.  

Terminada  la  descarga  e  instalación  cerramos  el  Android  SDK  Manager.  

 

 

Emulador  de  dispositivo  Android  y  Dispositivo  Virtual  Android  (Android  Virtual  Devices,  AVD)  Emulador  Android  y  Android  Virtual  Device  

El  SDK  de  Android  contiene  un  emulador  de  dispositivos  Android.  Este  emulador  se  puede  utilizar  para  ejecutar  un  dispositivo  virtual  de  Android  (AVD),  que  emula  un  teléfono  Android  real.  Este  emulador  se  muestra  en  la  siguiente  captura  de  pantalla.  

Page 15: Manual Inicio Android (1).pdf

 

  14  

 

AVDs   le   permiten   probar   sus   aplicaciones   de   Android   en   diferentes   versiones   y   configuraciones   de  Android  sin  acceso  al  hardware  real.  

Durante   la   creación  de   su  AVD   se  define   la   configuración  para   el   dispositivo   virtual.   Esto   incluye,   por  ejemplo,  la  resolución,  la  versión  de  la  API  de  Android  y  la  densidad  de  la  pantalla.  

Se  pueden  definir  varios  AVDs  con  diferentes  configuraciones  y  comenzar  en  paralelo.  Esto   le  permite  probar  diferentes  configuraciones  de  los  dispositivos  a  la  vez.  

Atajos  para  el  emulador  de  dispositivos  Android  

La  siguiente  tabla  muestra  los  accesos  directos  útiles  para  trabajar  con  una  AVD.  

 

Page 16: Manual Inicio Android (1).pdf

 

  15  

Tabla  1.  Atajos  para  el  emulador  de  dispositivos  de  Android  

ATAJO     DESCRIPCIÓN  

ALT+ENTER    MAXIMIZA  EL  EMULADOR.  

CTRL+F11     CAMBIA  LA  ORIENTACIÓN  DEL  EMULADOR  DE  HORIZONTAL  A  VERTICAL  Y  VICEVERSA.    

F8     ENCIENDE  Y  APAGA  LA  RED  

 

Google  vs.  Android  AVD  

Durante  la  creación  de  una  AVD  usted  decide  si  desea  crear  un  dispositivo  Android  o  un  dispositivo  de  Google.  

Un  AVD   creado  para  Android   contiene   los   programas   del   proyecto   de  Android  Open   Source.  Un  AVD  creada  para  la  API  de  Google  contiene  código  específico  adicional  de  Google.  

AVDs  creadas  con   la  API  de  Google   le  permiten  probar  aplicaciones  que  utilizan  Google  Play  Services,  por  ejemplo,  la  nueva  API  de  Google  Maps  o  los  nuevos  servicios  de  localización.  

Optimización  de  Velocidad  

Durante   la  creación  de  un  emulador  se  puede  elegir  si   se  desea,  ya  sea  Snapshot  o  habilitar  Use  Host  GPU.  Si  selecciona  la  opción  de  Snapshot,  la  segunda  vez  que  se  inicia  el  dispositivo  se  inicia  muy  rápido,  debido  a  que  la  AVD  almacena  su  estado  en  caso  que  lo  cierre.  Si  selecciona  Usar  Host  GPU  la  AVD  utiliza  la  tarjeta  gráfica  de  su  ordenador  directamente,  hace  el  renderizado  en  el  dispositivo  emulado  mucho  más  rápido.  

Page 17: Manual Inicio Android (1).pdf

 

  16  

 

Emulador  Intel  

El  emulador  de  Intel  que  puede  ser  instalado  a  través  del  Administrador  SDK  de  Android  es  mucho  más  rápido  en  la  ejecución  en  el  hardware  de  Intel  /  AMD.  Si  lo  instala  a  través  del  SDK,  es  necesario  instalar  también  el  controlador  que  se  encuentra  en  el  directorio  de  instalación  del  dispositivo.  

 

Page 18: Manual Inicio Android (1).pdf

 

  17  

Emulador  Alternativo  

Hay  alternativas  disponibles  al  emulador  por  defecto  de  Android.  Por  ejemplo,  el  emulador  Genymotion  es  relativamente  rápido  en  la  puesta  en  marcha  y  ejecución  de  proyectos  de  Android  

Ejercicio:  Crear  e  iniciar  Android  Virtual  Device  Target  (objetivo)  

En  este  ejercicio  se  creará  e  iniciará  un  AVD.  Aunque  si  se  tiene  un  dispositivo  Android  real  disponible,  te  debería  de  ser   familiar   la  creación  y  uso  de   los  AVDs.  Los  dispositivos  virtuales  dan   la  posibilidad  para  probar  su  aplicación  en  otras  versiones  de  Android  y  especificar  configuraciones.  

Crear  el  AVD  

Definir  un  nuevo  Android  Virtual  Device  (AVD)  abriendo  el  AVD  Manager  via  Window>Android  Virtual  Device  Manager  y  presionar  el  botón  New  

 

Ingresar  valores  similares  a  los  de  la  siguiente  toma  de  pantalla.  

Page 19: Manual Inicio Android (1).pdf

 

  18  

 

Nota  

Asegurarse  que   la  opción  Use  Host  GPU  este   seleccionada.  Esto  permite  que  el  AVD  use   la  unidad  de  procesamiento  gráfico  (GPU)  de  su  computadora  y  hace  el  renderizado  mucho  más  rápido.  

Después   presionar   el   botón  OK.   Esto   creará   la   configuración   del   AVD   y   lo   desplegará   bajo   la   lista   de  dispositivos  virtuales  disponibles.  

Page 20: Manual Inicio Android (1).pdf

 

  19  

Iniciar  tu  AVD  

Seleccionar  la  nueva  entrada  y  presionar  el  botón  Start.  Seleccionar  Launch  en  el  siguiente  dialogo.  

 

Advertencia  

No  interrumpa  el  proceso  de  inicio,  esto  podría  corrompir  el  AVD.  El  primer  inicio  puede  tomar  arriba  de  10  minutos   en  máquinas   viejas.   En   una  maquina  moderna   típicamente   toma   1   –   3  minutos   para   un  nuevo  AVD  al  iniciar.  

Después  de  iniciado  el  AVD,  puedes  controlar  la  GUI  con  el  mouse.  El  emulador  puede  proveer  acceso  a  los  botones  del  teléfono  vía  un  menú  del  lado  derecho  del  emulador.  

Page 21: Manual Inicio Android (1).pdf

 

  20  

 

Tip  

Una  vez  inicializado,  no  detener  el  AVD  durante  el  desarrollo.  Si  se  cambia  algo  en  la  aplicación  y  quiere  probar  una  nueva  versión,  simplemente  hay  que  correr  o  ejecutar  de  nuevo  la  aplicación  en  el  AVD.  

Ejercicio:  Crear  aplicación  Android  en  Eclipse  Asistente  de  proyectos  Android  

Las   herramientas   de  Android   en   Eclipse   proporciona   asistentes   para   aplicaciones   de  Android.   En   este  ejercicio  se  utiliza  el  asistente  de  creación  de  proyecto  para  crear  una  aplicación  de  Android  basada  en  una  plantilla.  

Nota  

El  propósito  de  este  ejercicio  es  demostrar  el  proceso  de  desarrollo.  Los  elemnots  creados  se  explicarán  más  adelante.  

Crear  proyecto  Android  

Para  crear  un  nuevo  proyecto  Android  seleccione  File  →  New  →  Other...  →  Android  →  Android  Project  en  el  menú.  Introduzca  los  datos  de  ajuste  de  la  siguiente  tabla  en  la  primera  página  del  asistente.  

Page 22: Manual Inicio Android (1).pdf

 

  21  

Tabla  2.  Ajuste  para  su  proyecto  Android  

Property   Value  

Application  Name   Test  App  

Project  Name   com.utm.primero  

Package  Name   com.utm.primero  API  (Minimum,  Target,  Compile  with)   14    

 

Pulse  el  botón  Siguiente  y  asegúrese  de  habilitar  la  opción  Create  a  launcher  icon  (Crear  un  icono  de  lanzador  )  y  Create  activity  (Crear  actividad).  

Page 23: Manual Inicio Android (1).pdf

 

  22  

 

 

Pulse  el  botón  Next  y  seleccione  la  plantilla  BlankActivity.  Pulse  el  botón  Next    para  proceder.  

Page 24: Manual Inicio Android (1).pdf

 

  23  

 

Introduce  los  siguientes  datos  en  el  cuadro  de  diálogo  para  la  plantilla  BlankActivity.  La  selección  se  representa  en  la  pantalla  después  de  la  tabla.  

Tabla  3.  Valores  para  la  plantilla  

Parameter   Value  

Activity   MainActivity  

Layout   activity_main  

Navigation  Type   none  

 

Page 25: Manual Inicio Android (1).pdf

 

  24  

 

Pulse  el  botón  Finish.  El  asistente  le  puede  pedir  que  instale  la  biblioteca  de  compatibilidad.  Si  es  así,  seleccione  para  instalarla.  

 

Page 26: Manual Inicio Android (1).pdf

 

  25  

Ejercicio:  Inicie  la  aplicación  Android  generada  Iniciar  AVD  

Si  aún  no  lo  ha  hecho,  cree  e  inicie  un  dispositivo  virtual  de  Android  (AVD).  La  versión  de  Android  que  usted  seleccione  debe  adaptarse  a  la  versión  mínima  API  de  la  aplicación  Android.  

Después   del   arranque   aparece   la   pantalla   de   bienvenida   de   su  AVD   como   se  muestra   en   la   siguiente  captura  de  pantalla.  

 

Una  vez  que  esté  listo,  desbloqueé  su  emulador.  

Page 27: Manual Inicio Android (1).pdf

 

  26  

 

Inicicar  la  aplicación  

Seleccione  el  proyecto  Android,  haga  clic  derecho  sobre  él  y  seleccione  Run-­‐As  →  Android  Aplication.  

 

Page 28: Manual Inicio Android (1).pdf

 

  27  

Se  le  puede  pedir  si  el  Android  Developer  Tools  deben  supervisar  los  mensajes.  Seleccione  Yes  en  este  caso  y  pulse  el  botón  OK.  

 

Así  se  inicia  la  aplicación  en  la  AVD.  La  aplicación  iniciada  es  una  aplicación  muy  simple  que  sólo  muestra  la  cadena  ¡Hola,  mundo!  .  

 

Integración  de  ADT  dentro  de  Eclipse  Integración  de  Android  dentro  de  la  perspectiva  Java  

La  herramienta  Android  se  integra  con  la  perspectiva  Java.  Incluye  botones  en  la  barra  de  herramientas  para  administrar  la  configuración  de  Android  con  el  gestor  Android  SDK,  crea  nuevos  AVDs  y  archivos  de  configuración,  así  como  contiene  asistentes  para  crear  nuevos  proyectos  Android.  

La  siguiente  captura  de  pantalla  resalta  la  barra  de  herramientas  de  Android  

 

1. Android  SDK  Manager  2. Manejo  e  inicio  de  AVDs  

Asistentes  de  Android  

1            2  

Page 29: Manual Inicio Android (1).pdf

 

  28  

Se  encontrarán  los  asistentes  específicos  de  Android  bajo  File  →  New  →  Other...  →  Android  como  se  muestra  en  la  siguiente  captura  de  pantalla.  Estos  asistentes  le  permiten  crear  proyectos  para  Android.  

 

Perspectiva  DDMS  Perspectiva  Android  

ADT  agrega  la  perspectiva  DDMS  (Dalvik  Device  Monitoring  Service)  para  interactuar  con  tu  dispositivo  Android  (virtual)  y  tu  aplicación  Android.  Selecciona  Window  →  Open  Perspective  →  Other...  →  DDMS  para   abrir   esta   perspectiva.   Aquí   se   agrupan   varias   vistas   que   pueden   ser   usadas   de   forma  independiente.  

En  la  parte  izquierda  se  muestran  los  dispositivos  Android  conectados  y  los  procesos  en  ejecución  en  el  dispositivo.   El   lado   derecho   es   un   conjunto   de   vistas   con   diferentes   propósitos.   Puede   seleccionar  procesos  y  desencadenar  acciones  de  la  barra  de  herramientas,  por  ejemplo,  iniciar  una  traza  o  detener  el  proceso.  

Page 30: Manual Inicio Android (1).pdf

 

  29  

 

File  Explorer  

El  explorar  de  archivos  permite  navegar  el  sistema  de  archivos  del  dispositivo  de  Android  ya  sea  virtual  o  real  conectado.  

Partes  de  una  aplicación  Android  Aplicación  Android  

Una   aplicación   para   Android   es   una   sola   unidad   instalable   que   se   puede   iniciar   y   utilizar   de   forma  independiente  de  otras  aplicaciones  de  Android.  

Una  aplicación  Android  puede  tener  una  clase  de  la  aplicación  la  cual  puede  ser  instanciada  tan  pronto  como  se  inicia  la  aplicación  y  es  el  último  componente  que  se  detiene  si  la  aplicación  se  detiene.  

Una  aplicación  Android  consta  de  componentes  de  software  de  Android  y  de  archivos  de  recursos.  

Los   componentes   de   una   aplicación   Android   pueden   conectar   a   otras   aplicaciones   Android.   De   esta  manera  se  puede  crear  tareas  entre  aplicaciones.  

Componentes  de  software  Android  

Los  siguientes  componentes  de  software  pueden  ser  definidos  en  las  aplicaciones  Android  

• Activities  (Actividades)  • Services  (Servicios)  • Broadcast  Receivers  (receivers)  

Page 31: Manual Inicio Android (1).pdf

 

  30  

• Content  providers  (providers)  

Contexto  

Instancia  de  la  clase  android.content.Context  que  proporciona  la  conexión  con  el  sistema  Android  el  cual  ejecuta  la  aplicación.  Por  ejemplo,  se  puede  revisar  el  tamaño  de  la  pantalla  del  dispositivo  actual  via  el  Context.  

También  da  acceso  a  los  recursos  del  proyecto.  Es  la  interfaz  a  la  información  global  sobre  el  entorno  de  la  aplicación.  

La   clase  Context   también  proporciona   acceso   a   los   servicios,   esto   es,   el  manejador   de   alarmas  para  disparar  eventos  basados  en  el  tiempo.  

Las  actividades    y  servicios  extienden  de  la  clase  Context.  Por  lo  tanto,  se  pueden  utilizar  directamente  para  acceder  al  Context.  

Vistazo  a  los  componentes  de  una  aplicación  Android  Activity  (Actividad)  

Una  activity  es  la  representación  visual  de  una  aplicación  Android.  Una  aplicación  Android  ouede  tener  varias  actividades.  

Las   actividades   usan   views   (vistas)   y   fragments   (fragmentos)   para   crear     la   interfaz   de   usuario   e  interactuar  con  el  usuario.  

BroadcastReceiver  

Un   broadcast   receiver   (receiver)   puede   ser   registrado   para   escuchar   los   mensajes   del   sistema   y   los  intents.  Un  receiver  será  notificado  por  el  sistema  Android  si  el  evento  especificado  ocurre  

Por  ejemplo,  se  puede  registrar  un  receiver  para  el  vento  en  el  que  el  sistema  android  finaliza  el  proceso  de  arranque.  O  se  puede  registrar  para  el  evento  en  el  que  el  estado  del  telefono  cambia,  esto  es,  que  alguien  llama.  

Service  (Servicio)  

Un   servicio   realiza   tareas   sin   proporcionar   una   interfaz   de   usuario.   Se   pueden   comunicar   con   otros  componentes  Android,  por  ejemplo,  a  través  de  los  receptores  de  radiodifusión  y  notificará  al  usuario  a  través  del  marco  de  la  notificación  de  Android.  

 

Page 32: Manual Inicio Android (1).pdf

 

  31  

ContentProvider  

Un  content  provider  (provider)  define  una  interfaz  estructurada  de  datos  de  la  aplicación.  Un  proveedor  puede  ser  utilizado  para  acceder  a  datos  dentro  de  una  aplicación,  pero  también  se  puede  utilizar  para  compartir  datos  con  otras  aplicaciones.  

Componentes   base   en   las   interfaces   de  usuario  en  Android  La  siguiente  descripción  da  una  visión  general  de  la  interfaz  de  usuario  relacionada  con  los  componentes  más  importantes  y  partes  de  una  aplicación  Android.  

Acitivity  (Actividad)  

Las  activities  son  la  base  para  las  aplicaciones  de  usuario  en  Android.  Estas  ya  fueron  vistas  en  la  sección  anterior.  

Fragments  (Fragmentos)  

Los   Fragments   son   componentes   los   cuales   corren   en   el   contexto   de   una   activity.   Un   fragment  encapsula   código   de   aplicaciones   así   qué   es   más   fácil   reutilizar   y   soportar   dispositivos   de   diferentes  tamaños.  

La   siguiente   imagen   muestra   una   activity   llamada   MainActivity.   En   una   pantalla   más   pequeña   que  muestra   sólo   un   fragmento   y   permite   que   el   usuario   se   desplaza   a   otro   fragmento.   En   una   pantalla  panorámica  que  muestra  dos  fragmentos.  

 

Page 33: Manual Inicio Android (1).pdf

 

  32  

 

Los  fragmentos  son  componentes  opcionales  que  le  permiten  reutilizar  los  componentes  de  interfaz  de  usuario  para  diferentes  configuraciones  de  dispositivos.  

Views  y  control  de  distribución    

Las  views  son  widgets  de  interfaz  de  usuario,  por  ejemplo,  botones  o  campos  de  texto.  Las  views  tienen  atributos  que  pueden  utilizarse  para  configurar  su  apariencia  y  comportamiento.  

A  ViewGroup  es  responsable  de  la  organización  de  otras  vistas.  También  se  conoce  como  controlador  de  distribución   (layout   manager).   La   clase   base   para   estos   controladores   de   distribución   es   la   clase  android.view.ViewGroup  que  extiende   (hereda)  de   la  clase  android.view.View que  es   la  clase  base  para  las  vistas.  

Los  layout  manager  pueden  etar  anidados  para  crear  layout  más  complejos.  

Diseños  específicos  de  configuración  de  dispositivos  

La  interfaz  de  usuario  para  las  activities  suelen  definirse  a  través  de  archivos  XML  (archivos  de  diseño).  Es   posible   definir   archivos   de   diseño   para   la   configuración   de   dispositivos   diferentes,   por   ejemplo,  basados  en  la  anchura  disponible  del  dispositivo  real  que  ejecuta  la  aplicación.  

Otros  elementos  importantes  de  Android  Pantalla  principal  y  la  pantalla  de  bloqueo  de  widgets  

Los   widgets   son   componentes   interactivos   que   se   utilizan   principalmente   en   la   pantalla   de   inicio   de  Android.  Ellos  exhiben  típicamente  algún  tipo  de  datos  y  permiten  al  usuario  realizar  acciones  con  ellos.  

Page 34: Manual Inicio Android (1).pdf

 

  33  

Por  ejemplo,  un  control  puede  mostrar  un  breve  resumen  de  los  nuevos  mensajes  de  correo  electrónico  y,  si  el  usuario  selecciona  un  correo  electrónico,  puede  iniciar  la  aplicación  de  correo  electrónico  con  el  correo  electrónico  seleccionado.  

Para  evitar  confusiones  con  los  views  (que  también  se  llaman  widgets),  este  texto  utiliza  el  termino  de  los  widgets  en  la  pantalla  de  inicio,  si  se  habla  de  widgets.  

Live  Wallpapers  

Los  Live  Wallpapers  permiten  crear  fondos  animados  para  la  pantalla  de  inicio  de  Android.  

El  Android  Manifest  La  configuración  de  la  aplicación  para  Android  

Los   componentes   y   configuración   de   una   aplicación   para   Android,   se   describen   en   el   archivo  AndroidManifest.xml.  Este  archivo  se  conoce  como  el  archivo  de  manifiesto  o  el  manifiesto.  

El   manifiesto   también   especifica   metadatos   adicionales   para   la   aplicación,   por   ejemplo,   iconos   y   el  número  de  versión  de  la  aplicación.  

Este  archivo  es   leído  por  el  sistema  Android  durante   la   instalación  de   la  aplicación.  El  sistema  Android  evalúa  este  archivo  de  configuración  y  determina  las  capacidades  de  la  aplicación.  

Declarar  los  componentes  en  el  archivo  de  manifiesto  

Todas  las  activities,  servicios  y  contenido  de  los  content  provider  de  la  aplicación  se  deben  declarar  de  forma  estática  en  este  archivo.  Los  broadcast  receivers  pueden  ser  definidos  estáticamente  en  el  archivo  de  manifiesto  o  dinámicamente  al  tiempo  de  ejecución  de  la  aplicación.  

Permisos  

El  archivo  de  manifiesto  de  Android  también  debe  contener  los  permisos  necesarios  para  la  aplicación.  Por  ejemplo,  si  la  aplicación  requiere  acceso  a  la  red,  se  debe  especificar  aquí.  

Ejemplo  del  archivo  AndroidManifes.xml  

El  siguiente  listado  muestra  un  ejemplo  para  un  simple  archivo  AndroidManifest.xml.  

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.rssfeed" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19" />

Page 35: Manual Inicio Android (1).pdf

 

  34  

<uses-permission android:name="android.permission.INTERNET" /> <application android:name="RssApplication" android:allowBackup="false" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="RssfeedActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DetailActivity" android:label="Details" > </activity> <activity android:name="MyPreferenceActivity" > </activity> <service android:name="RssDownloadService" > </service> </application> </manifest>  

El  manifiesto  de  Android  Versión  y  paquete  

El   atributo   de  package   define   el   paquete   base   para   los   objetos   Java   que   se   hace   referencia   en   este  archivo.   Si   un   objeto   de   Java   se   encuentra   dentro   de   un   paquete   diferente,   se   debe   declarar   con   el  nombre  completo  del  paquete  calificado.  

Google   Play   requiere   que   cada   aplicación  Android   utilice   su   propio   nombre   único   de   paquete.   Por   lo  tanto  es  un  buen  hábito  el  usar   su  nombre  de  dominio   inverso  aquí.  Esto  evitará  colisiones  con  otras  aplicaciones  de  Android.  

android:versionName y   android:versionCode especifican   la   version   de   su   aplicación.  versionName es  lo  que  ve  el  usuario  y  puede  ser  cualquier  cadena.  

versionCode debe  ser  un  entero.  El  Android  Market  determina  si  se  debe  llevar  a  cabo  una  actualización  de  las  aplicaciones   para   la   instalación   existente   basado   en   el   versionCode.   Por   lo   general,   comienza   con   "1"   y  aumenta  este  valor  por  uno  si  sale  una  nueva  versión  de  su  aplicación.  

Page 36: Manual Inicio Android (1).pdf

 

  35  

 

 

 

 

   

Page 37: Manual Inicio Android (1).pdf

 

  36  

Ciclo  de  vida  de  una  Activity  A  medida  que  el  usuario  navega  a  través  de,  fuera  de,  y  de  regreso  a  su  aplicación,  las  instancias  de  las  Activities  cambian  entre   los  diferentes  estados  de  su  ciclo  de  vida  en   las   transiciones  de   la  aplicación.  Por  ejemplo,   cuando  su  actividad  se   inicia  por  primera  vez,   se   trata  de  un  primer  plano  del   sistema  y  recibe  la  atención  del  usuario.  Durante  este  proceso,  el  sistema  Android  llama  a  una  serie  de  métodos  de  ciclo  de  vida  sobre  la  actividad  en  la  que  se  configura  la  interfaz  de  usuario  y  otros  componentes.  Si  el  usuario  realiza  una  acción  que   inicia  otra  actividad  o  cambia  a  otra  aplicación,  el   sistema   llama  a  otro  conjunto   de   métodos   de   ciclo   de   vida   en   su   activity   a   medida   que   avanza   hacia   el   fondo   (donde   la  actividad  ya  no  es  visible,  pero  la  instancia  y  su  estado  permanecen  intactos).  

Dentro  de  los  métodos  de  llamadas  del    ciclo  de  vida,  puedes  declarar  cómo  se  comportará  tu  activity  cuando   el   usuario   abandone   o   reingrese   a   la   activity.   Por   ejemplo,   si   se   está   construyendo   un  reproductor  de  vídeo  con  streaming,  se  podría  hacer  una  pausa  al  vídeo  y  terminar  la  conexión  de  red  cuando  el  usuario  cambia  a  otra  aplicación.  Cuando  el  usuario  vuelve,  puede  volver  a  conectarse  a  la  red  y  permitir  al  usuario  reanudar  el  vídeo  desde  el  mismo  punto.  

Entendiendo  el  flujo  del  ciclo  de  vida  

Durante  la  vida  de  una  actividad,  el  sistema  llama  a  un  conjunto  básico  de  los  métodos  de  ciclo  de  vida  en  una   secuencia   similar   a  una  pirámide  escalonada.  Es  decir,   cada  etapa  del   ciclo  de  actividad  es  un  paso  separado  en  la  pirámide.  A  medida  que  el  sistema  crea  una  nueva  instancia  de  una  activity,  cada  método  de  devolución  de  llamada  mueve  el  estado  de  activity  un  paso  hacia  la  cima.  La  parte  superior  de   la   pirámide   es   el   punto   en   el   que   la   actividad   se   ejecuta   en   el   primer   plano   y   el   usuario   puede  interactuar  con  él  (Imagen  8).  

 

Imagen  8  

Page 38: Manual Inicio Android (1).pdf

 

  37  

Dependiendo  de  la  complejidad  de  la  actividad,  probablemente  no  es  necesario  implementar  todos  los  métodos  del  ciclo  de  vida.  Sin  embargo,  es  importante  que  se  entienda  cada  uno  y  ponerlos  en  práctica  garantiza  que  la  aplicación  se  comporte  de  la  forma  en  que  los  usuarios  esperan.  La  implementación  de  los  métodos  de  ciclo  de  vida  de  la  activity  apropiadamente  asegura  que  la  aplicación  se  comporte  bien  en  varias  situaciones,  incluyendo  que:  

• No  bloquee  si  el  usuario   recibe  una   llamada  telefónica  o  cambia  a  otra  aplicación  mientras  se  utiliza  la  aplicación.  

• No  consume  valiosos  recursos  del  sistema  cuando  el  usuario  no  está  usando  activamente.  • No  pierde  el  progreso  del  usuario  si  salen  de  su  aplicación  y  volver  a  ella  más  adelante.  • No   bloquee   o   perder   el   progreso   del   usuario   cuando   la   pantalla   cambia   entre   orientación  

vertical  u  horizontal.  

Hay  varias   situaciones  en   las  que   las   transiciones  de  una  activity  entre   los  diferentes  estados  ocurren  como  se  ilustran  en  la  Imagen  8.  Sin  embargo,  sólo  tres  de  estos  estados  puede  ser  estático.  Es  decir,  la  activity  puede  existir  en  uno  de  los  tres  estados  para  un  período  de  tiempo  prolongado:  

• Resumed:  En  este  estado,  la  activity  está  en  el  primer  plano  y  el  usuario  puede  interactuar  con  él.  (También  se  refiere  a  veces  como  el  estado  "corriendo").  

• Paused:  En  este  estado,  la  activity  está  parcialmente  oculta  por  otra  activity,  la  otra  activity  que  está   en   el   primer   plano   es   semi-­‐transparente   o   no   cubre   toda   la   pantalla.   La   activity   que   se  detuvo  no  recibe  la  entrada  del  usuario  y  no  se  puede  ejecutar  ningún  código.  

• Stopped:  En  este  estado,  la  activity  está  completamente  oculta  y  no  visible  para  el  usuario,  sino  que  se  considera  que  está  en  el  fondo.  Mientras  está  detenida,  la  instancia  de  la  activity  y  toda  la   información   de   su   estado   como   variables   de   miembros   se   mantiene,   pero   no   se   puede  ejecutar  ningún  código.  

Los   otros   estados   (creado   e   iniciado)   son   transitorios   y   el   sistema   rápidamente   cambia   de   ellos   al  siguiente  estado  llamando  al  siguiente  ciclo  de  vida.  Es  decir,  después  de  que  el  sistema  llama  onCreate  (),  rápidamente  se  llama  OnStart  (),  que  rápidamente  es  seguido  por  onResume  ().  

 

Creación  y  manejo  de  Base  de  Datos  Existen  dos  formas  para  la  creación  o  utilización  de  bases  de  datos  en  Android:  

1. Diseñar   y   crear   la   base   de   datos   de  manera   externa   usando   alguna   aplicación   (en   este   caso  Navicat).  

2. Utilizacón  de  la  clase  SQLiteOpenHelper para  crear  la  estructura  de  la  base  de  datos  desde  el  código.  

Crear  la  BD  con  SQLite  en  Navicat.  

Page 39: Manual Inicio Android (1).pdf

 

  38  

1. Lo   primero   que   hay   que   hacer   es   abrir   el   Navicat   y   crear   una   nueva   conexión   a   una   base   de  datos  SQLite,  como  vemos  en  la  Imagen  9  

 

Imagen  9  

2. Escoger  un  nombre  a   la  conexión  en  nuestro  caso  se   llamará  bd_alumnos,  en   la  sección    Type  seleccionar  la  opción  New  SQLite  3,  y  en  la  sección  de  Database  File  debemos  de  especificar  un  lugar     donde   guardaremos   nuestra   base   de   datos   recientemente   creada   así   mismo   como   el  nombre  que  le  queremos  dar  al  archivo  en  la  Imagen  10  se  muestra  como  queda  configurada  mi  base  de  datos.  

 

Imagen  10  

Page 40: Manual Inicio Android (1).pdf

 

  39  

3. Para   crear   la   tabla   que   requerimos   hacemos   doble-­‐click   en   la   nueva   conexión   recién   creada,  después   aparece   una   opción   que   dice   “main”,   también   a   esta   le   damos   doble-­‐click   y   se  despliegan  varias  opciones  en  la  que  dice  Tables  hacemos  click  con  el  botón  derecho  y  del  menú  desplegable  seleccionamos  la  opción  New  Table  (Ver  Imagen  11).  

 

Imagen  11  

4. Crearemos  los  campos  que  llevará  la  BD,  debe  de  quedar  igual  a  como  se  muestra  en  la  Imagen  12.  

 

Imagen  12  

Page 41: Manual Inicio Android (1).pdf

 

  40  

5. Ahora  crearemos  una  índice,  esto  es  necesario  que  sea  realizado  para  todas  las  llaves  primarias  que  sean  creadas  con  auto  incremento,  para  realizar  esto  seleccionamos  la  pestaña  Indexes,  en  la  columna  Name  pondremos  un  nombre  al  índice  en  este  caso  será  id_alumno,  en  la  columna  Fields   al   seleccionarla   cambia   a   como   se  muestra   en   la   Imagen   13   y   damos   un   click   al   botón  encerrado  en  el  cuadro  rojo.  

 

Imagen  13  

6. En  la  ventana  que  es  mostrada  ahora,  ver  Imagen  14,  marcamos  el  checkbox  de  la  llave  primaria  y  en   la  columna  Sort  Order,  seleccionamos  la  opción  ASC  y  aceptamos  los  cambios  dando  click  en  el  botón  encerrado  en  el  cuadro  rojo.  

 

Imagen  14  

 

7. Al   guardar   las   modificaciones   si   no   existía   previamente   la   tabla   entonces   nos   pide   que   le  pongamos  un  nombre  a  la  tabla  así  como  se  muestra  en  la  Imagen  15.  

Page 42: Manual Inicio Android (1).pdf

 

  41  

 

Imagen  15  

8. En  este  punto  al  crear   la  nueva  tabla  ctl_alumnos  se  crea  una  tabla  dinámica  sqlite_sequence,  esta  tabla  lleva  el  control  de  la  secuencia  de  las  llaves  principales,  por  favor  de  no  modificar  esta  tabla  (Imagen  16).  

 

Imagen  16  

9. Android   solicita   que   la   base   de  datos   incluya   una   tabla   que   se   llama  android_metadata,   esta  tabla  debe  de  contener  un  solo  campo  de  nombre   locale   y  en   la   Imagen  17  se  muestra  cómo  debe  de  quedar  configurada  dicha  tabla.  

Page 43: Manual Inicio Android (1).pdf

 

  42  

 

Imagen  17  

Cargar  la  base  de  datos  en  el  proyecto  de  Android  

1. En  este  punto  es  necesario   recordar   la  ubicación  en   la  que  guardamos  nuestra  base  de  datos,  porque   necesitamos   copiar   dicho   archivo   a   la   carpeta   /res/assets   del   proyecto   android   que  estemos   trabajando,   esto   lo   podemos   realizar   desde   el   navegador   de   archivos   del   sistema  operativo  que  estemos  usando.  Ya  copiado  el  archivo,  que  para  casos  práctico  nuestro  archivo  se  debería  de  llamar  bd_alumnos.bd,    en  la  Imagen  18  vemos  un  ejemplo  de  cómo  debería  de  verse  la  estructura  de  archivos  de  nuestro  proyecto  después  de  copiar  el  archivo.  

 

Imagen  18  

Page 44: Manual Inicio Android (1).pdf

 

  43  

Cargar  la  base  de  datos  en  la  aplicación  para  poder  usarla  

1. Lo  primero  será  crear  un  paquete  nuevo  para  separar   los  archivos  relacionados  con  el  manejo  de   base   de   datos   de   los   del   manejo   de   las   activities,   el   nombre   del   nuevo   paquete   será  com.demo.proyectodemo.db.  

2. Ahora   crearemos   la   clase   java   DataBaseManager.java   la   cual   tendrá   varias   funciones   y/o  métodos:  

Método   Funcionalidad  DataBaseManager(Context  context)  

Constructor  

createDataBase()   Crea    una  base  de  datos  vacía  en  el  sistema  y  la  reescribe  con  tu  propia  base  de  datos  

checkDataBase()   Verifica   si   la   base   de   datos   ya   existe   para   evitar   re-­‐copiar   el   archivo  cada  vez  que  abres  la  aplicación  

copyDataBase()   Copia  tu  base  de  datos  desde  la  carpeta  local  assets  a  la  base  de  datos  vacía  recientemente  creada  en  el  sistema  de  carpetas,  para  que  pueda  ser  accesada  y  manipulada.  Esto  es  hecho  por  transferencia  de  flujo  de  bytes  

openDataBase()   Abre  la  base  de  datos  close()   Cierra  la  base  de  datos  

Tabla  4  

3. Lo  primero  que  haremos  será  declarar  unas  variables  globales  que  serán  utilizadas  en  diferentes  partes  de  la  clase,  como  se  muestra  en  la  Imagen  19.  

 

Imagen  19  

4. Lo  siguiente  que  haremos  será  declarar  el  constructor  de  la  clase  como  lo  vemos  en  la  Imagen  20.  

Page 45: Manual Inicio Android (1).pdf

 

  44  

 

Imagen  20  

5. Ahora  crearemos  una  método  que  verificará  si  la  base  de  datos  ya  existe,  esta  clase  solo  regresa  true   si   ya   existe   o   false   en   caso   de   no   existir,   dicho  método   se   llamará   checkDataBase(),   el  código  necesario  en  esta  clase  se  muestra  en  la  Imagen  21.  

 

Imagen  21  

6. El  siguiente  método  necesario  es  uno  que  nos  ayude  a  copiar  la  base  de  datos  que  tenemos  en  la   carpeta  assets   al   sistema  de  archivos  del  proyecto  para  que  pueda  ser  usada  y  manipulada  nuestra  base  de  datos,  este  método  tendrá  el  nombre  copyDataBase(),  y  la  copia  del  archivo  de  la  base  de  datos  desde  assets  hacía  el  sistema  de  archivos  de  la  aplicación  se  realiza  a  través  de  un  flujo  de  bytes,  el  código  de  dicho  método  lo  podemos  ver  en  la  Imagen  22.  

Page 46: Manual Inicio Android (1).pdf

 

  45  

 

Imagen  22  

7. Los   dos   métodos   anteriores   son   necesarios   puesto   que   son   utilizados   por   el   método  createDataBase()  ya  que  primero  valida  si  la  base  de  datos  ya  existe  y  en  caso  de  que  no  exista  entonces  copia  la  base  de  datos.  Esto  lo  podemos  ver  en  la  Imagen  23.  

 

Imagen  23  

Page 47: Manual Inicio Android (1).pdf

 

  46  

8. Por   último   falta   agregar   dos  métodos  muy   importantes   para   abrir   y   cerrar   la   base   de   datos,  estos  métodos  son  openDataBase()  y  close(),  en   la   Imagen  24  podemos  observar  el  código  de  estos  dos  métodos.  

 

Imagen  24  

 

9. Ahora   que   ya   tenemos   todo   lo   necesario   para   agregar   nuestra   base   de   datos   a   nuestra  aplicación   será   necesario   que   creemos   un  métoodo   que   inicie   todo   el   proceso   de   revisión   y  creación  de  la  base  de  datos,  una  buena  opción  es  hacerlo  en  el  momento  en  el  que  se  pone  en  marcha   la   aplicación,   digamos   que   podemos   crear   un   Splash   y   en   este   momento   hacer   lo  relacionado  con  la  base  de  datos,  esto  con  ayuda  de  la  clase  AsyncTask  

10. Lo   primero   será   crear   una   activity   llamada   SplashScreen.java, y   declararla   como   la  pantalla  de  inicio  de  nuestra  aplicación  dentron  del  Manifest  de  nuestra  aplicación  (en  realidad  el  Asynctask  lo  podemos  usar  en  el  momento  que  lo  deseemos,  podríamos  no  usar  una  pantalla  de  Splash,  y  hacerlo  directamente  en  nuestra  pantalla  de  inicio,  esto  es  a  decisión  suya  y  de  las  necesidades  del  proyecto).  

11. Ahora  es  cuestión  y  decisión  de  su  proyecto  como  diseñar  la  interfaz  del  layout  del  Splash  que  se  a   creado,  activity_splash_screen.xml,   por   cuestiones  de  economía  de   tiempo  yo   lo  diseñaré  muy  simple:  

Page 48: Manual Inicio Android (1).pdf

 

  47  

                                                                                   

12. Y   quedando   el   layout activity_splash_screen.xml como   se   muestra   a  continuación:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="#CECECE" tools:context=".SplashScreen" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="@string/hello_world" android:textSize="40sp" /> </RelativeLayout>

Page 49: Manual Inicio Android (1).pdf

 

  48  

13. El   código   de   la   clase  SplashScreen.java   es  muy   simple,   en   el  método  onCreate()se  carga  el   layout  que  se  va  a  utilizar  y  se  manda   llamar  a   la  subclase   interna  priva  que  se  creeo  dentro  de  esta  actividad.  

14. Ya  en  la  sublcase  sobreescribimos  los  métodos  doInBackground  y  onPostExecute,  en  el  primero  método  es  donde  se  crea  un  hilo  que  en  este  caso  será  el  que  se  encargue  de  ejecutar  el  método  de   comprobar   si   ya   existe   la   base   de   datos   o   hay   que   crearla,   el   segundo  método  indica   que   es   lo   que   se   hará   en   el   momento   que   se   haya   terminado   de   ejecutar   el   hilo,   en  nuestro  caso  sólo  carga  la  siguiente  activity.  

15. Y  este  es  el  código  final  que  tenemos:  

import java.io.IOException; import com.utm.primero.database.DataBaseManager; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; public class SplashScreen extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash_screen); /* * Se manda llamar o ejecutar la subclase que hereda * de la clase AsynTask * */ new VerificarBaseDatos().execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.splash_screen, menu); return true; } /* * Creamos la subclase que hereda de AsyncTask * */ private class VerificarBaseDatos extends AsyncTask<Void, Void,

Page 50: Manual Inicio Android (1).pdf

 

  49  

Void> { /* * No realizamos nada en el método onPreExecute * */ @Override protected void onPreExecute() { super.onPreExecute(); } /* * En el método doInBackground es el momento * donde verificaremos la existencia de la base de datos * */ @Override protected Void doInBackground(Void... params) { DataBaseManager myDbHelper = new DataBaseManager(SplashScreen.this); try { myDbHelper.createDataBase(); } catch (IOException e) { throw new Error("Imposible crear la base de datos"); } return null; } /* * Al momento de terminar la ejecución del método * doInBackground será momento de ejecutar al método * onPostExecute*/ @Override protected void onPostExecute(Void result) { super.onPostExecute(result); // Después de ejecutar la verificación de la base de datos // cerrarremos esta actividad y lanzaremos la nnueva actividad Intent i = new Intent(SplashScreen.this, MainActivity.class); startActivity(i); // cerrar definitivamente esta actividad // para evitar que en el momento de dar Back se ejecute de nuevo } } }

16. Cabe  recordar  o  hacer  notar  algunas  cosas:  

Page 51: Manual Inicio Android (1).pdf

 

  50  

a. Esta   es   sólo   una   forma   de   poder   verificar   si   ya   existe   la   base   de   datos   instalada   en  nuestro   teléfono,   no   basta   con   que   la   base   de   datos   este   en   el   proyecto   o   en   la  aplicación,   tienen   que   estar   instalada   en   el   teléfono   y   esto   es   lo   que   hace   todo   este  procedimiento.  

b. La  clase  AsyncTask  es  una  forma  mucho  más  fácil  de  hacer  tareas  asíncronas,  y  puede  ser  utiizada  en  cualquier  parte  de  nuestro  sistema,  no  solo  en  el  splash  o  para  verificar  que  la  base  de  datos  está  ya  instalada.  

 

 

Creación  de  la  Base  de  Datos  con  código  desde  la  aplicación  

Al   tener   ya   creado   algún   proyecto   que   pueda   utilizar   o   necesitar   una   base   de   datos   de   SQLite   será  necesario  que  creemos  un  nuevo  paquete  para  guardar  las  clases  que  manejarán  la  base  de  datos.  Como  caso  de  ejemplo  se  creará  el  paquete  com.example.tareasqlite.database (claro,  siempre  y  cuando  ya  tengamos  hecho  un  proyecto,  en  caso  de  no  tenerlo  debemos  de  iniciar  un  proyecto  nuevo).  En  este  caso  se  crearán  dos  clases  DataBaseHelper.java  y  DBAdapter.java como  se  muestra  en  la  siguiente  imagen  

 

Veamos   que   contienen   las   clases   que   acabamos   de   crear,   la   primera   en   analizar   es   la   clase  DataBaseHelper.java dicha   clase   extiende   (hereda)   de   la   clase   SQLiteOpenHelper. A  continuación  tenemos  el  contenido  completo  de  la  clase  la  cuál  vamos  a  ir  explicando  líneas  abajo:  

package com.example.tareasqlite.database; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DataBaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "applicationdata"; private static final int DATABASE_VERSION = 1; //Sentencia para crear la BD private static final String DATABASE_CREATE = "create table todo

Page 52: Manual Inicio Android (1).pdf

 

  51  

(_id integer primary key autoincrement, " + "categoria text not null, resumen text not null, descripcion text not null);"; public DataBaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } //Este método es llamado cuando se crea la BD @Override public void onCreate(SQLiteDatabase database) { database.execSQL(DATABASE_CREATE); } //Método que se llama cada vez que se actualiza la BD //Incrementa la versión @Override public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) { Log.w(DataBaseHelper.class.getName(), "Actualizando la BD desde la versión " + oldVersion + " a "+ newVersion + ", la cual destruirá todos los datos viejos"); database.execSQL("DROP TABLE IF EXISTS todo"); onCreate(database); } }  

Esta   clase   básicamente   nos   ayudará   a   definir   la   estructura   de   la   base   de   datos.   Al   inicio   de   la   clase  creamos   tres   constantes:   un   String   llamado  DATABASE_NAME   que   define   el   nombre   de   la   base   de  datos,   un   int   llamado  DATABASE_VERSION   que   pasará   el   número   de   versión   de   la   base   de   datos  cuando  es  creada,  y  la  consulta  que  nos  servirá  para  crear  la  base  de  datos.  

Todo  esto  se  define  desde  el  constructor  que  se  encuentra  líneas  abajo  en  esta  clase.  

El  método  onCreate()  es  el  que  ejecuta  la  consulta  CREATE  para  la  base  de  datos.  Por  otro  lado,  el  método  onUpgrade()  manejaremos  todas  las  acciones  que  necesitemos  cada  vez  que  se  actualice  la  base  de  datos;  en  este  caso,  únicamente  estamos  mandando  mensajes  en  el  Log.  

Ahora,   pasemos   a   la   clase   DBAdapter.java   que   es   la   que   contendrá   toda   la   funcionalidad   para  realizar  consultas,  crear  y  editar  cada  uno  de  los  items  que  manejará  la  aplicación.  

import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase;

Page 53: Manual Inicio Android (1).pdf

 

  52  

public class DBAdapter { //Campos de la BD public static final String KEY_ROWID = "_id"; public static final String KEY_CATEGORY = "categoria"; public static final String KEY_SUMMARY = "resumen"; public static final String KEY_DESCRIPTION = "descripcion"; private static final String DATABASE_TABLE = "todo"; private Context context; private SQLiteDatabase database; private DataBaseHelper dbHelper; public DBAdapter(Context context) { this.context = context; } public DBAdapter open() throws SQLException{ dbHelper = new DataBaseHelper(context); database = dbHelper.getWritableDatabase(); return this; } public void close(){ dbHelper.close(); } /** * * Crea una nueva tarea, si esto va bien retorna * la rowId de la tarea, de lo contrario retorna -1 * * */ public long crearNuevaTarea(String categoria, String resumen, String descripcion){ ContentValues inicialValues = crearContentValues(categoria, resumen, descripcion); return database.insert(DATABASE_TABLE, null, inicialValues); } //Actualiza la tarea public boolean updateTarea(long rowId, String categoria, String resumen, String descripcion){ ContentValues actulizaValues = crearContentValues(categoria, resumen, descripcion); return database.update(DATABASE_TABLE,actulizaValues, KEY_ROWID + "=" +rowId, null) > 0; }

Page 54: Manual Inicio Android (1).pdf

 

  53  

//Borrar la tarea public boolean deleteTarea(long rowId){ return database.delete(DATABASE_TABLE, KEY_ROWID + "=" +rowId, null) > 0; } // Retorna un cursor que contiene todos los items public Cursor recuperaTodos(){ String[] columnas = {KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION}; return database.query(DATABASE_TABLE, columnas, null, null, null, null, null); } // Retorna un Cursor que contiene la info de una tarea public Cursor recuperaTarea(long rowId) throws SQLException{ String[] columnas = {KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY, KEY_DESCRIPTION}; Cursor mCursor = database.query(true, DATABASE_TABLE, columnas, KEY_ROWID + "=" +rowId, null, null, null, null, null); if(mCursor != null){ mCursor.moveToFirst(); } return mCursor; } private ContentValues crearContentValues(String categoria, String resumen, String descripcion) { ContentValues values = new ContentValues(); values.put(KEY_CATEGORY, categoria); values.put(KEY_DESCRIPTION, descripcion); values.put(KEY_SUMMARY, resumen); return values; } }

Vamos   a   explicar   cada   uno   de   los  métodos   que   estamos   creando.   La   primera   parte   corresponde   a   la  creación  de  las  constantes  y  variables  que  vamos  a  utilizar.  Las  constantes  son  cada  una  de  las  columnas  de   la   tabla   que   almacenará   la   información   de   la   aplicación.   Después   tenemos   tres   variables   que  corresponden  al  contexto  de  la  aplicación,  a  la  base  de  datos  y  al  helper  para  manipular  las  consultas  y  funciones  con  SQLite.  

En   el   constructor   únicamente   definiremos   el   contexto   de   la   aplicación.   Después,   tenemos   el  método  open()  que  sirve  para  preparar  la  base  de  datos  a  modo  que  podamos  escribir  datos  en  ella,  para  ello  

Page 55: Manual Inicio Android (1).pdf

 

  54  

se   abre   la   base   de   datos   a   través   del   objeto   de   tipo  DBHelper.   En   este   método   ocupamos   una  SQLException  pues  es  probable  que  a  veces  ocurran  errores  en  esta  parte  y  esto  nos   servirá  para  conocerlos.  El  método  close()  sirve  para  cerrar  el  helper.  Si  has  trabajado  con  Java  y  MySQL,  verás  que   es   algo  muy   parecido   a   lo   que   tenemos   que   hacer   para  manejar   bases   de   datos   a   través   de   un  conector.  

Posteriormente,  tenemos  los  métodos  para  crear,  actualizar,  borrar  y  consultar  los  elementos  de  la  base  de  datos  a  través  de   la  clase  ContentValues  nos  permitirán  crear  y  actualizar  valores  dentro  de   la  base  de  datos.  A  través  de  esta  clase  podemos  manipular  la  correspondencia  entre  identificador/valor,  utilizando  el  nombre  de  la  columna  como  el  identificador  al  cuál  únicamente  le  definiremos  el  valor  para  actualizar  o  crear  un  nuevo  elemento  dentro  de  la  base  de  datos.  

Manejo  de  SQLite  en  Android  

SQLite   es   un   motor   de   bases   de   datos   muy   popular   en   la   actualidad   por   ofrecer   características   tan  interesantes   como   su   pequeño   tamaño,   no   necesitar   servidor,   precisar   poca   configuración,   ser  transaccional  y  por  supuesto  ser  de  código  libre.  

Android   incorpora   de   serie   todas   las   herramientas   necesarias   para   la   creación   y   gestión   de   bases   de  datos   SQLite,   y   entre   ellas   una   completa   API   para   llevar   a   cabo   de   manera   sencilla   todas   las   tareas  necesarias.   Por   el  momento  nos   limitaremos   a   ver   el   código  necesario   para   crear   una  base  de  datos,  insertaremos   algún   dato   de   prueba,   y   veremos   cómo   podemos   comprobar   que   todo   funciona  correctamente.      

Por  el  momento  hemos  visto  dos  formas  de  crear  y/o  utilizar  una  base  de  datos  SQLite  en  Android,  más  adelante  en  este  manual  veremos  la  forma  de  utilizar  el  segundo  método    (Creación  de  la  Base  de  Datos  con  código  desde  la  aplicación)  en  un  proyecto  de  ejemplo.  

SQLiteOpenHelper  

Para   crear   y   trabajar   con   bases   de   datos   en   Android,   es   necesario   hacer   uso   de   la   clase  SQLiteOpenHelper.  En  esta  clase  es  necesario  sobrescribir  los  métodos  onCreate()  para  crear  la  base  de   datos,   y   onUpgrade()   para   actualizar   la   base   de   datos   en   caso   de   que   existan   cambios   en   el  esquema  de  la  misma.  Ambos  métodos  reciben  como  parámetro  un  objeto  SQLiteDatabase.  

SQLiteOpenHelper   ofrece   los   métodos  getReadableDatabase()   y  getWriteableDatabase()  para  trabajar  con  un  objeto  SQLiteDatabase  y  poder  tener  acceso  de  lectura  y  escritura  sobre  una  base  de  datos.  

SQLDatabase  y  Cursor  

La  clase  SQLiteDatabase  provee  los  métodos  insert(),  update()  y  delete()  y  execSQL()  que  nos  ayuda  a  ejecutar  sentencias  SQL  directamente.  El  objeto  ContentValues  permite  definir  claves  y  valores  en   las  sentencias  Insert  y  Update.  La  clave  (key)  corresponde  a   la  columna  y  el  valor  es  el  valor  para  la  columna.  

Page 56: Manual Inicio Android (1).pdf

 

  55  

Las   consultas   se   pueden   crear   a   través   del   método  rawQuery()   que   acepta   como   parámetro   una  sentencia   en   SQL   o   el   método   query()   que   proporciona   una   interfaz   para   especificar   los   datos  dinámicos  o  un  objeto  de  tipo  SQLiteQueryBuilder.  SQLiteBuilder  es  similar  a  la  interfaz  de  un  proveedor  de  contenidos  por  lo  que  suele  utilizarse  con  Content Providers.  Hay  que  saber  también  que  toda  consulta  que  realicemos  nos  retornará  un  objeto  de  tipo  Cursor.    

Para  definir   la   llave  primaria  de  una  base  de  datos  es   indispensable  hacer  uso  del   identificador  _id   ya  que  muchas  de  las  funciones  con  las  que  trabajaremos  toman  en  cuenta  este  estándar.    

En  Android,  la  forma  típica  para  crear,  actualizar,  y  conectar  con  una  base  de  datos  SQLite  será  a  través  de  una  clase  auxiliar  llamada  SQLiteOpenHelper,  o  para  ser  más  exactos,  de  una  clase  propia  que  derive  de  ella  y  que  debemos  personalizar  para  adaptarnos  a  las  necesidades  concretas  de  nuestra  aplicación.  

La   API   de   SQLite   de   Android   proporciona   dos   alternativas   para   realizar   operaciones   sobre   la   base   de  datos  que  no  devuelven  resultados  (entre  ellas  la  inserción/actualización/eliminación  de  registros,  pero  también  la  creación  de  tablas,  de  índices,  etc).  

El  primero  de  ellos,  es  el  método  execSQL()  de  la  clase  SQLiteDatabase.  Este  método  permite  ejecutar  cualquier   sentencia   SQL   sobre   la   base   de   datos,   siempre   que   ésta   no   devuelva   resultados.   Para   ello,  simplemente   aportaremos   como   parámetro   de   entrada   de   este   método   la   cadena   de   texto  correspondiente  con  la  sentencia  SQL.  

La  segunda  de  las  alternativas  disponibles  en  la  API  de  Android  es  utilizar  los  métodos  insert(),  update()  y  delete()   proporcionados   también   con   la   clase  SQLiteDatabase.   Estos  métodos   permiten   realizar   las  tareas   de   inserción,   actualización   y   eliminación   de   registros   de   una   forma   algo  más   paramétrica   que  execSQL(),  separando  tablas,  valores  y  condiciones  en  parámetros  independientes  de  estos  métodos.  

Empecemos   por   el   método   insert()   para   insertar   nuevos   registros   en   la   base   de   datos.   Este  método  recibe  tres  parámetros,  el  primero  de  ellos  será  el  nombre  de   la  tabla,  el  tercero  serán   los  valores  del  registro  a   insertar,   y  el   segundo   lo  obviaremos  por  el  momento  ya  que   tan  sólo   se  hace  necesario  en  casos  muy  puntuales   (por   ejemplo   para   poder   insertar   registros   completamente   vacíos),   en   cualquier  otro  caso  pasaremos  con  valor  null  este  segundo  parámetro.  

Los   valores   a   insertar   los   pasaremos   como   elementos   de   una   colección   de   tipo   ContentValues.   Esta  colección   es   de   tipo   diccionario,   donde   almacenaremos  parejas   de   clave-­‐valor,   donde   la   clave   será   el  nombre  de  cada  campo  y  el  valor  será  el  dato  correspondiente  a   insertar  en  dicho  campo.  Veamos   la  Imagen  26:  

 

Imagen  25  

Page 57: Manual Inicio Android (1).pdf

 

  56  

Los  métodos  update()  y  delete()  se  utilizarán  de  forma  muy  parecida  a  ésta,  con  la  salvedad  de  que  recibirán  un  parámetro  adicional  con  la  condición  WHERE  de  la  sentencia  SQL.  Por  ejemplo,  para  actualizar  el  email  del  usuario  de  nombre  ‘usu1’  haríamos  lo  siguiente:  

 

Imagen  26  

Como  podemos  ver,   como  tercer  parámetro  del  método  update()  pasamos  directamente   la   condición  del   UPDATE   tal   como   lo   haríamos   en   la   cláusula   WHERE   en   una   sentencia   SQL   normal.   El   método  delete()  se  utilizaría  de  forma  análoga.  Por  ejemplo  para  eliminar  el  registro  del  usuario  ‘usu2’  haríamos  lo  siguiente:  

 

Imagen  27  

Como  vemos,  volvemos  a  pasar  como  primer  parámetro  el  nombre  de  la  tabla  y  en  segundo  lugar  la  condición  WHERE.  Por  supuesto,  si  no  necesitáramos  ninguna  condición,  podríamos  dejar  como  null  en  este  parámetro.  

Un  último  detalle  sobre  estos  métodos.  Tanto  en  el  caso  de  execSQL()  como  en  los  casos  de  update()  o  delete()  podemos  utilizar  argumentos  dentro  de  las  condiciones  de  la  sentencia  SQL.  Esto  no  es  más  que  partes  variables  de  la  sentencia  SQL  que  aportaremos  en  un  array  de  valores  aparte,  lo  que  nos  evitará  pasar  por  la  situación  típica  en  la  que  tenemos  que  construir  una  sentencia  SQL  concatenando  cadenas  de  texto  y  variables  para  formar  el  comando  SQL  final.  Estos  argumentos  SQL  se  indicarán  con  el  símbolo  ‘?’,  y  los  valores  de  dichos  argumentos  deben  pasarse  en  el  array  en  el  mismo  orden  que  aparecen  en  la  sentencia  SQL.  Así,  por  ejemplo,  podemos  escribir  instrucciones  como  la  siguiente:  

 

Imagen  28  

Esta  forma  de  pasar  a  la  sentencia  SQL  determinados  datos  variables  puede  ayudarnos  además  a  escribir  código  más  limpio  y  evitar  posibles  errores.  

Page 58: Manual Inicio Android (1).pdf

 

  57  

De   forma   análoga   a   lo   que   vimos   para   las   sentencias   de   modificación   de   datos,   vamos   a   tener   dos  opciones  principales  para   recuperar   registros  de  una  base  de  datos   SQLite  en  Android.   La  primera  de  ellas   utilizando   directamente   un   comando   de   selección   SQL,   y   como   segunda   opción   utilizando   un  método  específico  donde  parametrizáremos  la  consulta  a  la  base  de  datos.  

Para   la   primera   opción   utilizaremos   el  método   rawQuery()   de   la   clase   SQLiteDatabase.   Este  método  recibe   directamente   como   parámetro   un   comando   SQL   completo,   donde   indicamos   los   campos   a  recuperar  y   los  criterios  de  selección.  El   resultado  de   la  consulta   lo  obtendremos  en   forma  de  cursor,  que   posteriormente   podremos   recorrer   para   procesar   los   registros   recuperados.   Sirva   la   siguiente  consulta  a  modo  de  ejemplo:  

 

Imagen  29  

Como  en  el  caso  de  los  métodos  de  modificación  de  datos,  también  podemos  añadir  a  este  método  una  lista  de  argumentos  variables  que  hayamos  indicado  en  el  comando  SQL  con  el  símbolo  ‘?‘,  por  ejemplo  así:  

 

Imagen  30  

Como   segunda   opción   para   recuperar   datos   podemos   utilizar   el   método   query()   de   la   clase  SQLiteDatabase.  Este  método  recibe  varios  parámetros:  el  nombre  de  la  tabla,  un  array  con  los  nombre  de  campos  a  recuperar,  la  cláusula  WHERE,  un  array  con  los  argumentos  variables  incluidos  en  el  WHERE  (si   los  hay,  null   en   caso   contrario),   la   cláusula  GROUP  BY   si   existe,   la   cláusula  HAVING   si   existe,   y  por  último   la   cláusula   ORDER   BY   si   existe.   Opcionalmente,   se   puede   incluir   un   parámetro   al   final   más  indicando   el   número   máximo   de   registros   que   queremos   que   nos   devuelva   la   consulta.   Veamos   el  mismo  ejemplo  anterior  utilizando  el  método  query():  

 

Imagen  31  

Como   vemos,   los   resultados   se   devuelven   nuevamente   en   un   objeto  Cursor   que   deberemos   recorrer  para  procesar  los  datos  obtenidos.  

Para  recorrer  y  manipular  el  cursor  devuelto  por  cualquiera  de  los  dos  métodos  mencionados  tenemos  a  nuestra  disposición  varios  métodos  de  la  clase  Cursor,  entre  los  que  destacamos  dos  de  los  dedicados  a  recorrer  el  cursor  de  forma  secuencial  y  en  orden  natural:  

• moveToFirst():  mueve  el  puntero  del  cursor  al  primer  registro  devuelto.  

Page 59: Manual Inicio Android (1).pdf

 

  58  

• moveToNext():  mueve  el  puntero  del  cursor  al  siguiente  registro  devuelto.  

Los  métodos  moveToFirst()  y  moveToNext()  devuelven  TRUE  en  caso  de  haber  realizado  el  movimiento  correspondiente  del  puntero  sin  errores,  es  decir,   siempre  que  exista  un  primer   registro  o  un  registro  siguiente,  respectivamente.  

Una   vez   posicionados   en   cada   registro   podremos   utilizar   cualquiera   de   los   métodos  getXXX(índice_columna)   existentes  para  cada   tipo  de  dato  para   recuperar  el  dato  de  cada  campo  del  registro   actual   del   cursor.   Así,   si   queremos   recuperar   por   ejemplo   la   segunda   columna   del   registro  actual,   y   ésta   contiene   un   campo   alfanumérico,   haremos   la   llamada   getString(1)   [NOTA:   los   índices  comienzan  por  0,  por   lo  que   la  segunda  columna  tiene   índice  1],  en  caso  de  contener  un  dato  de  tipo  real  llamaríamos  a  getDouble(1),  y  de  forma  análoga  para  todos  los  tipos  de  datos  existentes.  

Con  todo  esto  en  cuenta,  veamos  cómo  podríamos  recorrer  el  cursor  devuelto  por  el  ejemplo  anterior:  

 

Imagen  32  

Además  de  los  métodos  comentados  de  la  clase  Cursor  existen  muchos  más  que  nos  pueden  ser  útiles  en   muchas   ocasiones.   Por   ejemplo,   getCount()   te   dirá   el   número   total   de   registros   devueltos   en   el  cursor,  getColumnName(i)  devuelve  el  nombre  de  la  columna  con  índice  i,  moveToPosition(i)  mueve  el  puntero   del   cursor   al   registro   con   índice   i,   etc.   Podemos     consultar   la   lista   completa   de   métodos  disponibles  en  la  clase  Cursor  en  la  documentación  oficial  de  Android.  

Creando  un  Navigation  Drawer  No   hace   mucho   para   poder   implementar   este   en   nuestras   aplicaciones   de   Android    uno   mismo  debía    implementar  toda   la   funcionalidad  por  su  cuenta  o  utilizar  alguna   librería  de  alguien  ya   lo  halla  hecho.  Pero  por  suerte  en  el  ultimo  Google  I/O  2013  se  anuncio  oficialmente  que  se  incluiría  dentro  de  la  support   library  una  funcionalidad  llamada    Navigation  Drawer  que  es  la  que  justamente  nos  permite  implementar  esto,  gracias  a  esto  podemos  dotar  a  nuestras  apps  desde  versiones  antiguas  de  Android    esta  funcionalidad.  

Page 60: Manual Inicio Android (1).pdf

 

  59  

Lo  primero  que  debemos  de  hacer  es  asegurarnos  de  que  tenemos  la  versión  r19.0.1  de  Android  Support  Library  en  el  SDK  Manager,  en  el  caso  de  no  tenerlo  debemos  de  instalarla  desde  el  SDK  Manager.  

 

Nota  

Para  casos  de  este  manual  supondremos  que  ya  tenemos  un  proyecto  creado,  en  el  caso  de  que  no  sea  así  será  necesario  que  se  cree  uno  nuevo  y  seguir  el  manual  desde  este  punto.  

 

 

Después  de  verificar  de  que  tenemos  la  Support  Library  instalada  y  disponible  para  nuestro  proyecto  vamos  a  crear  nuestro  layout  que  será  el  esqueleto  de  nuestra  UI.  

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Vista para el contenido principal --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff"/> <!-- Navigation Drawer --> <ListView android:id="@+id/drawerIzquierdo" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" android:background="#E5E5E5" > </ListView> </android.support.v4.widget.DrawerLayout>

El  contenedor  principal  es  el  DrawerLayout  este  básicamente  es  el  que  permite  deslizar  la  vista  en  este  caso  será  el  ListView.  

Page 61: Manual Inicio Android (1).pdf

 

  60  

La  posición  de   deslizamiento   dentro   del   layout   es   controlado   por   la   sig.  propiedad    android:layout_gravity este  puede  ser:  left , right o start y end.  

Para  darnos  una  idea  al  finalizar  el  tutorial  seremos  capaces  de  implementar  una  UI  de  este  tipo.  

         

 

 

 

 

 

 

 

 

 

 

                                                   

Como   ven   dentro   del   FrameLayout   ira   el   contenido   principal  mientras   que   el   Listview   será   el   que   se  desplace   horizontalmente   ya   sea   clickeando   en   el   botón   del   ActionBar   o   arrastrándolo   tocando   la  pantalla.  

Ahora  vamos  a  la  parte  de  la  Activity  principal  

import android.app.Activity; import android.os.Bundle; import android.support.v4.widget.DrawerLayout; import android.view.Menu; import android.widget.ListView; public class MainActivity extends Activity { private ListView mDrawerList; private DrawerLayout mDrawerLayout; @Override

FrameLayout  ListView  

Page 62: Manual Inicio Android (1).pdf

 

  61  

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Drawer Layout

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

//Lista mDrawerList = (ListView) findViewById(R.id.drawerIzquierdo); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }

Es   muy   simple,   con   solamente   declarar   el   layout   ya   funcionaria,   en   este   caso   declaramos   el  DrawerLayout  y  ListView.  

Si  corremos  la  app  en  este  punto  y  deslizamos  el  dedo  de  forma  horizontal  desde  el  extremo  izquierdo  de  la  pantalla  hacia  dentro  veremos  como  se  desplaza  el  menú,  en  este  punto  todavía  no  se  incluyo  el  contenido  del  ListView  ni  el  ActionBar.  

Page 63: Manual Inicio Android (1).pdf

 

  62  

 

A   continuación   veremos   el   diseño  del  Menú  Vertical   y    como  agregar   opciones,   el  manejo  de   esto   es  igual   que   en   cualquier   aplicación   común   definiendo   su   layout,   implementar   un   Adaptador   especifico  para  este  en  el  caso  que  fuese  necesario,  etc..  

Diseño:  

La  idea  es  que  por  mas  que  sea  un  ejemplo  puedan  adquirir  conocimientos  para  dotar  a  sus  aplicaciones  con  una  interfaz  moderna  similar  a  las  que  ya  todos  conocemos,  obviamente  no  llegaremos  a  tanto  ya  que  se  necesita  mucho  diseño  pero  podemos  tratar  de  inspirarnos  de  ellas,  en  este  caso  está  basado  en  la  de  Google+  como  lo  vemos  en  la  siguiente  imagen.  

Page 64: Manual Inicio Android (1).pdf

 

  63  

 

Para  nuestro  ejemplo  lo  que  tendremos  es  lo  siguiente:  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

encabezado_drawer.xml  

 

item_drawer.xml  

Page 65: Manual Inicio Android (1).pdf

 

  64  

Como  se  puede  ver  al  principio  se   incluye  un  header  que  solamente  cumple  una  función  estética  pero  podría   incluirse   la   foto   de   perfil   del   usuario,   nombre,   etc.   Mas   adelante   veremos   como   integrarlos  dentro  del  ListView.  

/res/layout/encabezado_drawer.xml  

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/headerBackground" android:layout_width="fill_parent" android:layout_height="150dp" android:scaleType="centerCrop" android:src="@drawable/header" /> </FrameLayout>

Como  podemos  ver  nada  del  otro  mundo  un  FrameLayout  con  una  imagen  dentro.  

/res/layout/ítem_drawer.xml    

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/icon" android:layout_width="25dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:layout_centerVertical="true" /> <TextView android:id="@+id/title_item" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_toRightOf="@+id/icon" android:textColor="#111" android:gravity="center_vertical" android:paddingRight="40dp" android:paddingTop="15dp" android:paddingBottom="15dp"

Page 66: Manual Inicio Android (1).pdf

 

  65  

android:text="@string/app_name" /> </RelativeLayout>  

Para   pode   agregar   opciones   al  menú   se   agregan   tanto   las   opciones   como   la   imagen   que   cada   botón  debe  tener  dentro  del  /res/values/string.xml.  

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">ToDoSQLite</string> <string name="hello_world">Hello world!</string> <string name="title_activity_tareas">TareasActivity</string> <!-- Lista de elementos que aparecen en la navegación --> <string-array name="nav_options"> <item >ToDo</item> <item >Conversor</item> <item >Perfil</item> <item >Configuración</item> <item >Conversor</item> </string-array> <!-- Lista de iconos de navegacion --> <string-array name="nav_iconos"> <item >@drawable/ic_action_go_to_today</item> <item >@drawable/ic_action_merge</item> <item >@drawable/ic_action_person</item> <item >@drawable/ic_action_good</item> <item >@drawable/ic_action_cloud</item> </string-array> </resources>

En   la   primera   sección   he   declarado   un   array   de   Strings   nav_options   luego   otro   de  drawables  nav_iconos,    esta  es  una  forma  fácil  y  rápida  de  poder  declarar  estos  aunque  también  pudo  haberse  declarado   mediante   java   en   la   actividad   principal,   en   el   caso   que   el   contenido  fuese  dinámico  esta  opción  del  xml  no  seria  viable.  

Para  poder   facilitar  el  uso  del  menú  en  el  adaptador  que  veremos   luego  he  creado  una  clase   llamada  Items.java  en  esta  básicamente  se  declaran  los    métodos  para  asignarle  un  nombre  y  una  imagen.  

public class Items { private String titulo; private int icono; public Items(String titulo, int icono) { this.titulo = titulo; this.icono = icono; }

Page 67: Manual Inicio Android (1).pdf

 

  66  

public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } public int getIcono() { return icono; } public void setIcono(int icono) { this.icono = icono; } }

Volviendo  a  nuestra  activity  prinicipal  añadiremos  el  resto  de  cogido  para  obtener  los  datos  desde  el  archivos  strings.xml:  

import java.util.ArrayList; import android.app.Activity; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.widget.DrawerLayout; import android.view.Menu; import android.view.View; import android.widget.ListView; public class MainActivity extends Activity { private String[] titulos; private ListView mDrawerList; private ArrayList<Items> NavItems; private TypedArray NavIconos; NavigationAdapter NavAdapter; private DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Drawer Layout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); //Lista mDrawerList = (ListView) findViewById(R.id.drawerIzquierdo);

Page 68: Manual Inicio Android (1).pdf

 

  67  

//Declaramos el header el cual será el layout de encabezado_drawer.xml View encabezado = getLayoutInflater().inflate(R.layout.encabezado_drawer, null); //Establecer el encabezado mDrawerList.addHeaderView(encabezado); //Tomamos listado de imgs desde drawable NavIconos = getResources().obtainTypedArray(R.array.nav_iconos); //Tomamos listado de titulos desde el string-array de los recursos @string/nav_options titulos = getResources().getStringArray(R.array.nav_options); //Listado de titulos de barra de navegación NavItems = new ArrayList<Items>(); //Agregamos objetos Item_objct al array //ToDo NavItems.add(new Items(titulos[0], NavIconos.getResourceId(0, -1))); //Conversor NavItems.add(new Items(titulos[1], NavIconos.getResourceId(1, -1))); //Eventos NavItems.add(new Items(titulos[2], NavIconos.getResourceId(2, -1))); //Lugares NavItems.add(new Items(titulos[3], NavIconos.getResourceId(3, -1))); //Etiquetas NavItems.add(new Items(titulos[4], NavIconos.getResourceId(4, -1))); //Declaramos y seteamos nuestro adaptador al cual le pasamos el array con los titulos NavAdapter= new NavigationAdapter(this,NavItems); mDrawerList.setAdapter(NavAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } Aquí   podemos   observar   que   ya   estamos   integrando   encabezado_drawer.xml dentro   del  ListView (mDrawerList.addHeaderView(encabezado);),   luego   tomamos   desde   los  resources   el   array   de   drawables,   añadimos   uno   a   uno   los   elementos   del   menú   al   arraylist  NavItems en   cada   uno   de   estos   agregamos   un   objeto Items   en   donde   le   pasamos  la  posición  dentro  del  array  de   títulos  y   la   imagen.  Al   final  declaramos  el  adaptador  NavAdapter al  cual  le  pasamos  el  arraylist.    Una  parte  muy   importante   es   el   Adapter,   por   lo   cual   lo   veremos   en   una   sección   de  Adapaters,   en   el  

Page 69: Manual Inicio Android (1).pdf

 

  68  

listado  siguiente  podemos  ver  el  Adapter  que  se  diseña  para  nuestro  ejemplo.  Primero  habrá  crear  una  nueva   clase   que   herede   de   la   clase   BaseAdapter, dicha   clase   la   llamaremos  NavigationAdapter.java  import java.util.ArrayList; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class NavigationAdapter extends BaseAdapter { private Activity mActivity; ArrayList<Items> arrayItems; public NavigationAdapter(Activity mActivity, ArrayList<Items> arrayItems) { super(); this.mActivity = mActivity; this.arrayItems = arrayItems; } @Override public int getCount() { // TODO Auto-generated method stub return arrayItems.size(); } //Retorna objeto Items del array list @Override public Object getItem(int position) { // TODO Auto-generated method stub return arrayItems.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } //Declaramos clase estática, la cual representa la fila public static class Fila{ TextView tituloItem; ImageView icono; }

Page 70: Manual Inicio Android (1).pdf

 

  69  

@Override public View getView(int position, View convertView, ViewGroup arg2) { Fila view; LayoutInflater inflator = mActivity.getLayoutInflater(); if(convertView == null){ view = new Fila(); //Crear objeto item y obtenerlo del array Items item = arrayItems.get(position); convertView = inflator.inflate(R.layout.item_drawer, null); //Titulo view.tituloItem = (TextView) convertView.findViewById(R.id.title_item); //Establecer en el campo titulo el nombre correspondiente obtenido del objeto item view.tituloItem.setText(item.getTitulo()); //Icono view.icono = (ImageView) convertView.findViewById(R.id.icon); //Seteo del icono view.icono.setImageResource(item.getIcono()); convertView.setTag(view); }else { view = (Fila) convertView.getTag(); } return convertView; } } Lo   que   simplemente   hace   es   tomar   del   objeto   extraído   del   Arraylist   el   texto   y   la   imagen   para  luego  asignársela  a  su  correspondiente  elemento.  En  este  punto  nuestra  aplicación  permite  utilizar  la  navegación  deslizable  de  momento  solo  funcionara  con   versiones   de   Android   superiores   o   iguales   a   4.0,   en   el   caso   de   que   se   necesite   o   se   deseé  implementar   este   control   para   versiones   anteriores   será   necesario   seguir   otro   procedimiento   para  agregar  librerías  para  hacerla  compatible  con  versiones  anteriores  de  Android.  Al  ejecutar  nuestro  proyecto  esto  es  lo  que  veríamos:    

Page 71: Manual Inicio Android (1).pdf

 

  70  

   El   siguiente   paso   será   el   de   incorporar   el   botón   para   abrir   y   cerrar   el   menú   de   navegación   y   como  asignarle  una  acción  a  la  pulsación  sobre  un  item  del  menú.    Abrir  y  Cerrar  menú  desde  un  ícono.  

Ahora  veremos  como  implementar  el  clasico  botón  para  abrir  y  cerrar  el  menú,  el  botón  se  mostrará  en  la  esquina  superior  izquierda  junto  al  título.  

 

 

 

 

 

Para  poder  realizar  esto  utilizaremos  una  clase  llamada  ActionBarDrawerToggle,  su    uso  es  muy  simple  como  veremos  a  continuación,  

import android.app.Activity; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.util.Log;

Page 72: Manual Inicio Android (1).pdf

 

  71  

import android.view.Menu; import android.view.View; public class MainActivity extends Activity { NavigationAdapter NavAdapter; private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Aquí va el resto del código previamente escrito... //Declaramos mDrawableToggle y las imgs a utilizar mDrawerToggle = new ActionBarDrawerToggle( this, /* Activity huesped*/ mDrawerLayout, /* objeto DrawerLayout */ R.drawable.ic_drawer, /* imagen del nav drawer */ R.string.app_name, /* "abrir drawer" descripción para accesibilidad */ R.string.hello_world /* "cerrar drawer" descripción para accesibilidad */ ) { public void onDrawerClosed(View view) { Log.e("Cerrado completo", "!!"); } public void onDrawerOpened(View drawerView) { Log.e("Apertura completa", "!!"); } }; //Establecemos que mDrawerToggle declarado anteriormente sea el DrawerListener mDrawerLayout.setDrawerListener(mDrawerToggle); //Establecemos que el ActionBar muestre el botón home getActionBar().setDisplayHomeAsUpEnabled(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }

Page 73: Manual Inicio Android (1).pdf

 

  72  

}  

En  el  método  onCreate()   se  declara   la  variable    mDrawerToggle  a   la  cual  hay  que  especificar  el  contexto,  el  drawerLayout,  el   icono  que  se  mostrará  en  el  botón  (disponible  en  el  pack  de  iconos  para  Actionbar   ),  y  2  Strings  de  descripción   (que  en  realidad  no  se  usan  en  este  ejemplo  pero  que  hay  que  especificarlos).   También   podemos   especificar   una   acción   al   abrir   y   cerrar   el   menú  en  onDrawerClosed()   y    onDrawerOpened(),   dar   un   vistazo   al   Logcat   durante   el  funcionamiento  de  la  aplicación.  

Mediante  mDrawerLayout.setDrawerListener(mDrawerToggle;    asignamos   cual   será   el  DrawerListener  que  utilizara  en  este  caso  será  nuestro  mDrawerToggle  .  

Luego   en   getActionBar().setDisplayHomeAsUpEnabled(true);  Establecemos   que   el  ActionBar  muestre  el  botón  del  Home  de  nuestra  aplicación.  

Si  corremos  la  aplicación  en  esta  parte  podemos  ver  como  al  presionar  el  icono  el  menú  se  cierra  y  abre  también  podrán  observar  que  este  se  desplaza  según  este  el  menú  abierto  o  no.  

Asignar  acción  a  la  pulsación  de  un  Item  del  menú  de  navegación  

Lo  primero  que  debemos  de  hacer  es  asignar  un  evento  a  cada  uno  de  los  ítems  de  la  lista,  para  poder  especificar  cada  opción  de  la  lista,  en  este  caso  lo  que  haremos  es  según  la  opción  del  menú  que  pulse  mostrará  un  fragment  especifico,  por  lo  que  para  cada  pantalla  habrá  que  definir  un  fragment  y  un  layout  para  esa  opción.  Para  efectos  del  presente  tutorial  crearemos  una  clase  nueva  que  reaccionará  al  toque  del  primer  ítem  de  la  lista,  dicha  clase  la  llamaremos  TareasFragment.java  y  hereda  de  la  clase  Fragment. A  continuación  podemos  ver  el  código  de  dicha  clase:  

import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class TareasFragment extends Fragment { public TareasFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.activity_tareas, container, false); return rootView; }

Page 74: Manual Inicio Android (1).pdf

 

  73  

}

Ya  cuando  se  tiene  listo  el  fragment  el  código  que  necesitamos  que  traiga  nuestra  clase  principal  será  el  siguiente:  

//Establecemos la accion al clickear sobre cualquier item del menu. //De la misma forma que hariamos en una app comun con un listview. mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) { MostrarFragment(position); } });

//Cuando la aplicacion cargue por defecto mostrar la opción Home MostrarFragment(1);

Dentro   de   OnCreate()   al   mDrawerList   le   asignamos   el   método   OnItemClickListener   y  dentro  hacemos  una   llamada  al  método  MostrarFragment(position) al   cual   hay  que  pasarle  como   parámetro   la   posición   de   la   opción   seleccionada   en   el   menú,   en   base   a   esto   mostrara   el  fragment  especifico.  

Luego  fuera  de  esto    indico  que  cuando  la  aplicación  cargue  muestre  la  opción  “ToDo”    por  defecto,  para  eso  le  paso  el  numero  1  el  cual  equivale  a  la  primer  opción  del  menú.  

//Cuando la aplicacion cargue por defecto mostrar la opción Home MostrarFragment(1);

Ver   los  comentarios  en  cada   línea  par  entender  como  funciona  el  método  MostrarFragment(int position)que   a   continuación   se   muestra,   este   método   también   va   en   la   clase  MainActivity.java  de  nuestro  proyecto:  

/*Pasando la posicion de la opcion en el menu nos mostrara el Fragment correspondiente*/ private void MostrarFragment(int position) { // update the main content by replacing fragments Fragment fragment = null; switch (position) { case 1: fragment = new TareasFragment(); break; /*case 2: fragment = new ProfileFragment(); break;*/

Page 75: Manual Inicio Android (1).pdf

 

  74  

default: //si no esta la opcion mostrara un toast y nos mandara a Home Toast.makeText(getApplicationContext(),"Opcion "+titulos[position-1]+"no disponible!", Toast.LENGTH_SHORT).show(); fragment = new TareasFragment(); position=1; break; } //Validamos si el fragment no es nulo if (fragment != null) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); // Actualizamos el contenido segun la opcion elegida mDrawerList.setItemChecked(position, true); mDrawerList.setSelection(position); //Cambiamos el titulo en donde decia " setTitle(titulos[position-1]); //Cerramos el menu deslizable mDrawerLayout.closeDrawer(mDrawerList); } else //Si el fragment es nulo mostramos un mensaje de error. Log.e("Error ", "MostrarFragment"+position); }

Con  esto  básicamente  ya  podemos  dotar  a  nuestra  aplicación  de  la  lógica  necesaria  para  poder  mostrar  cada  opción  del  menú,  luego  depende  de  cada  uno  lo  que    desee  mostrar  en  sus  aplicaciones.  

Por   último   hay   que   agregar   los   siguientes   métodos:   onPostCreate,

onConfigurationChanged, onOptionsItemSelected  para  sobrescribirlos.  

@Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync el estado del toggle despues de onRestoreInstanceState haya ocurrido. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Pasar el evento al ActionBarDrawerToggle, si este

Page 76: Manual Inicio Android (1).pdf

 

  75  

// regresa true, entonces este manejara el evento del touch // en el icono de la app if (mDrawerToggle.onOptionsItemSelected(item)) { Log.e("mDrawerToggle presionado", "x"); return true; } // Maneja los otros items de la action bar... return super.onOptionsItemSelected(item); }

En  este  punto  nuestra  clase  MainActivity.java se  vería  como  se  muestra  a  continuación.

import java.util.ArrayList; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity {

private String[] titulos; private ListView mDrawerList; private ArrayList<Items> NavItems; private TypedArray NavIconos; NavigationAdapter NavAdapter; private ActionBarDrawerToggle mDrawerToggle; private CharSequence mDrawerTitle; private CharSequence mTitle; private DrawerLayout mDrawerLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Drawer Layout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

Page 77: Manual Inicio Android (1).pdf

 

  76  

//Lista mDrawerList = (ListView) findViewById(R.id.drawerIzquierdo); //Declaramos el header el cual será el layout de encabezado_drawer.xml View encabezado = getLayoutInflater().inflate(R.layout.encabezado_drawer, null); //Establecer el encabezado mDrawerList.addHeaderView(encabezado); //Tomamos listado de imgs desde drawable NavIconos = getResources().obtainTypedArray(R.array.nav_iconos); //Tomamos listado de titulos desde el string-array de los recursos @string/nav_options titulos = getResources().getStringArray(R.array.nav_options); //Listado de titulos de barra de navegacion NavItems = new ArrayList<Items>(); //Agregamos objetos Item_objct al array //ToDo NavItems.add(new Items(titulos[0], NavIconos.getResourceId(0, -1))); //Conversor NavItems.add(new Items(titulos[1], NavIconos.getResourceId(1, -1))); //Eventos NavItems.add(new Items(titulos[2], NavIconos.getResourceId(2, -1))); //Lugares NavItems.add(new Items(titulos[3], NavIconos.getResourceId(3, -1))); //Etiquetas NavItems.add(new Items(titulos[4], NavIconos.getResourceId(4, -1))); //Declaramos y seteamos nuestrp adaptador al cual le pasamos el array con los titulos NavAdapter= new NavigationAdapter(this,NavItems); mDrawerList.setAdapter(NavAdapter); //Siempre vamos a mostrar el mismo titulo mTitle = mDrawerTitle = getTitle(); //Declaramos mDrawableToggle y las imgs a utilizar mDrawerToggle = new ActionBarDrawerToggle( this, /* Activity huesped*/ mDrawerLayout, /* objeto DrawerLayout */ R.drawable.ic_drawer, /* imagen del nav drawer */ R.string.app_name, /* "abrir drawer" descripción para accesibilidad */ R.string.hello_world /* "cerrar drawer" descripción para accesibilidad */ ) { public void onDrawerClosed(View view) {

Page 78: Manual Inicio Android (1).pdf

 

  77  

Log.e("Cerrado completo", "!!"); } public void onDrawerOpened(View drawerView) { Log.e("Apertura completa", "!!"); } }; //Establecemos que mDrawerToggle declarado anteriormente sea el DrawerListener mDrawerLayout.setDrawerListener(mDrawerToggle); //Establecemos que el ActionBar muestre el botón home getActionBar().setDisplayHomeAsUpEnabled(true); //Establecemos la accion al clickear sobre cualquier item del menu. //De la misma forma que hariamos en una app comun con un listview. mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) { MostrarFragment(position); } }); //Cuando la aplicacion cargue por defecto mostrar la opcion Home MostrarFragment(1); } /*Pasando la posicion de la opcion en el menu nos mostrara el Fragment correspondiente*/ private void MostrarFragment(int position) { // update the main content by replacing fragments Fragment fragment = null; switch (position) { case 1: fragment = new TareasFragment(); break; /*case 2: fragment = new ProfileFragment(); break;*/ default: //si no esta la opcion mostrara un toast y nos mandara a Home Toast.makeText(getApplicationContext(),"Opcion

Page 79: Manual Inicio Android (1).pdf

 

  78  

"+titulos[position-1]+"no disponible!", Toast.LENGTH_SHORT).show(); fragment = new TareasFragment(); position=1; break; } //Validamos si el fragment no es nulo if (fragment != null) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit(); // Actualizamos el contenido segun la opcion elegida mDrawerList.setItemChecked(position, true); mDrawerList.setSelection(position); //Cambiamos el titulo en donde decia " setTitle(titulos[position-1]); //Cerramos el menu deslizable mDrawerLayout.closeDrawer(mDrawerList); } else //Si el fragment es nulo mostramos un mensaje de error. Log.e("Error ", "MostrarFragment"+position); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync el estado del toggle despues de onRestoreInstanceState haya ocurrido. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Pasar el evento al ActionBarDrawerToggle, si este // regresa true, entonces este manejara el evento del touch // en el icono de la app if (mDrawerToggle.onOptionsItemSelected(item)) { Log.e("mDrawerToggle presionado", "x"); return true; } // Maneja los otros items de la action bar... return super.onOptionsItemSelected(item); } @Override

Page 80: Manual Inicio Android (1).pdf

 

  79  

public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }

Interactuar  con  una  Base  de  Datos  En   la   sección   "Creación   y   manejo   de   Base   de   DatosCreación   y   manejo   de   Base   de   Datos"   vimos   y  aprendimos   la   forma   de   cómo   crear   y   conectarse   con   una   base   de   datos,   además   de   haber   creado  algunos  métodos  para  realizar  consultas,  actualizaciones  y  borrado  de  datos  en  una  tabla.    

En  esta  parte  del  manual  procederemos  a  utilizar  estos  métodos  y  clases  para  utilizarlas  en  un  ejemplo  como  parte  del  proyecto  que  venimos  desarrollando  hasta  ahora,  para  lo  cual  vamos  a  modificar  algunas  clases   y   crear   algunas   nuevas,   así   como   crear   nuevos   layouts   y   algunos   nuevos   archivos   de   recursos,  manos  a  la  obra.  

Lo  primero  que  haremos  es  definir  lo  que  necesitamos  para  esto  necesitamos  la  siguiente  estructura:  

1. Una  actividad  para  desplegar  la  lista  de  tareas  que  el  usuario  vaya  agregando.  En  realidad  esta  ya   la   tenemos   creada   (ver   sección   "Asignar   acción   a   la   pulsación   de   un   Item   del   menú   de  navegación"),  pero  vamos  a  modificarla.  

2. Una  actividad  para  agregar  estas  tareas.  3. Una  clase  para  manejar  la  creación  de  la  base  de  datos  y  las  versiones  de  la  misma  (ver  

SQLiteOpenHelper.java  ).  4. Una  clase  para  manejar  la  lógica  del  uso  de  consultas  en  SQLite  de  la  aplicación  DBAdapter.java  

A  esta  altura  del  manual  ya  tenemos  solventados  los  puntos  3  y  4,  por  lo  tanto  vamos  a  empezar  a  ver  el  punto  1  y  posteriormente  el  2.  

Agregar  recursos  a  la  aplicación  

Ahora,  vamos  a  diseñar  los  recursos  extras  como  cadenas  de  texto  y  otro  tipo  de  información  que  necesitará  desplegar  la  aplicación.  

Primero,  vamos  a  crear  la  estructura  del  menú  de  opciones  de  la  aplicación.  Definimos  un  archivo  XML  llamado  tareas.xml  dentro  del  directorio  res  >  menu.  A  continuación  vemos    el  código  que  deberá  contener  este  archivo:  

<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/insertar"

Page 81: Manual Inicio Android (1).pdf

 

  80  

android:orderInCategory="100" android:showAsAction="never" android:title="@string/action_insertar"/> </menu>

El  archivo  strings.xml  que  ya  tenemos  como  parte  de  nuestro  proyecto  en  el  directorio  res  >  values  deberá  de  lucir  y/o  contener  todo  el  siguiente  código:  

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">ToDoSQLite</string> <string name="action_insertar">Insertar</string> <string name="hello_world">Hello world!</string> <string name="title_activity_tareas">TareasActivity</string> <string-array name="prioridades"> <item>Urgente</item> <item>Recordatorio</item> </string-array> <!-- Lista de elementos que aparecen en la navegación --> <string-array name="nav_options"> <item>ToDo</item> <item>Conversor</item> <item>Perfil</item> <item>Configuración</item> <item>Conversor</item> </string-array> <!-- Lista de iconos de navegacion --> <string-array name="nav_iconos"> <item>@drawable/ic_action_go_to_today</item> <item>@drawable/ic_action_merge</item> <item>@drawable/ic_action_person</item> <item>@drawable/ic_action_good</item> <item>@drawable/ic_action_cloud</item> </string-array> <string name="menu_insert">Agregar Tarea</string> <string name="menu_delete">Borrar Tarea</string> <string name="tarea_resumen">Nombre</string> <string name="tarea_descripcion">Borrar</string> <string name="tarea_editar_resumen">Nombre</string> <string name="tarea_editar_descripcion">Descripción</string> <string name="tarea_editar_confirmar">Aceptar</string> <string name="no_todos">Aún no existen elementos en la lista</string> </resources>  

Page 82: Manual Inicio Android (1).pdf

 

  81  

Diseño  de  layouts  

Vamos  a  definir  dos  archivos  de  layout,  uno  para  la  lista,  y  uno  para  las  filas.  A  continuación  veremos  el  código  del  archivo  activity_tareas.xml  del  directorio  res  >  layout  que  define  la  apariencia  de  la  lista  que  desplegará  la  información  de  la  base  de  datos.  

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/list_color" android:orientation="vertical" > <ListView android:id="@android:id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" > </ListView> <TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/no_todos" /> </LinearLayout>

En  el  siguiente  layout  vamos  a  hacer  uso  de  un  icono,  se  puede  utilizar  el  que  deseen  incluso  se  puede  omitir  y  no  hay  ningún  problema.  El  siguiente  archivo  de  layout  se  llama  row.xml  y  se  usará  para  darle  estilo  a  cada  una  de  las  filas  de  la  lista:  

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/icon" android:src="@drawable/reminder" android:layout_marginLeft="4dp" android:layout_marginTop="8dp" android:layout_marginRight="8dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/label" android:text="@string/hello_world" android:layout_height="wrap_content" android:textSize="20sp"

Page 83: Manual Inicio Android (1).pdf

 

  82  

android:layout_marginTop="6dp" android:layout_width="wrap_content" android:textColor="@color/negro" /> </LinearLayout>

Ahora  que  ya  hemos  definido  los  recursos,  layouts  y  las  clases  que  nos  ayudarán  a  manipular  la  parte  de  SQLite   en   Android.   Estamos   listos   para   crear   las   clases   que   nos   ayudarán   a   juntar   cada   una   de   estas  piezas.  

Agregar  clases  para  manejo  de  interacción  con  la  base  de  datos  

En  este  parte  vamos  a  dar  solución    a  los  puntos  1  y  2  que  vimos  al  inicio  de  esta  sección  (ver  Interactuar  con   una   Base   de   Datos),     para   lo   cual   primero   crearemos   una   nueva   activity   que   se   llamará  Details.java  en  dónde  vamos  a  presentar  el   formulario  de  creación  y  edición  de   items  para  cada  uno  de  los  elementos  que  seleccionemos  en  la  lista  principal.  

En   el   momento   de   crear   la   nueva   actividad   nos   creará   un   nuevo   layout   de   nombre  activity_details.xml,  vamos  a  editarlo  para  que  se  vea  gráficamente  de  la  siguiente  manera:  

 

Si  vemos  el  código  del  xml  veremos  esto:  

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"

Page 84: Manual Inicio Android (1).pdf

 

  83  

android:layout_height="fill_parent" android:background="@color/list_color" android:orientation="vertical" > <Spinner android:id="@+id/category" android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/prioridades" /> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <EditText android:id="@+id/todo_edit_summary" android:layout_width="wrap_content" android:layout_height="0dip" android:layout_weight="1" android:hint="Nombre" > </EditText> </LinearLayout> <EditText android:id="@+id/todo_edit_description" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:gravity="top" android:hint="Descripción" > </EditText> <Button android:id="@+id/todo_edit_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/tarea_editar_confirmar" /> </LinearLayout>

Ya  tenemos  diseñada   la  parte  del  cómo  se  verá   la  activity,  es  momento  de  pasar  a   la  etapa  en   la  que  escribiremos   el   código   que   controlará   el   proceso   de   consultas   a   la   base   de   datos,   de   inserción   y  modificación  de  datos  así  como  el  de  llenado  del  formulario  en  el  momento  que  hagamos  alguna  edición  de  una  “tarea”  previamente  creada.  

Page 85: Manual Inicio Android (1).pdf

 

  84  

En  todo  el  siguiente  listado  se  muestra  el  código  de  la  clase  DetailsActivity.java,  para  su  mayor  comprensión  se  recomienda  que  se  lean  los  comentarios  que  es  ahí  donde  se  explica  lo  mejor  posible  la  funcionalidad  del  código.  

import com.android.utm.todosqlite.database.DBAdapter; import android.app.Activity; import android.database.Cursor; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; public class DetailsActivity extends Activity { private EditText mTitleText; private EditText mBodyText; private Long mRowId; private DBAdapter mDbHelper; private Spinner mCategory; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); // Cargamos el layout de nuestro fragment setContentView(R.layout.activity_details); /* * Inicializamos los objetos y los enlazamos con * los elementos (views) del layout * */ mCategory = (Spinner) findViewById(R.id.category); mTitleText = (EditText) findViewById(R.id.todo_edit_summary); mBodyText = (EditText) findViewById(R.id.todo_edit_description); Button confirmButton = (Button) findViewById(R.id.todo_edit_button); /* * Recuperamos los parámetros que enviamos a esta * activity * */ mRowId = null; Bundle extras = getIntent().getExtras(); mRowId = (bundle == null) ? null : (Long)

Page 86: Manual Inicio Android (1).pdf

 

  85  

bundle.getSerializable(DBAdapter.KEY_ROWID); if (extras != null) { mRowId = extras.getLong(DBAdapter.KEY_ROWID); } // Mandamos llamar al método que se encargará de llenar los campos en caso de ser una edición populateFields(); /* * Le asignamos el evento de OnClickListener a nuetro botón * esto con la finalidad de que guarde los valores que tenemos * en nuestro formulario * */ confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); saveState(); finish(); } }); } /* * Método que permite llenar los campos del formulario * en el caso de que sea una edición, si no es una * edición los campos será dejados vacíos * */ private void populateFields() { /* * Confirmamos que a variable mRowId no está nula, * esto confirma que se trata de una edición * */ if (mRowId != null) { /*Recuperamos los datos de la tarea que coincide con la variable mRowId*/ Cursor todo = mDbHelper.recuperaTarea(mRowId); /* * El método startManagingCursor que se hereda de la clase Activity * nos sirve o nos ayuda para tener un mejor control del cursor, pues * este se adaptará al ciclo de vida de la activity, esto es que si * la activity es detenida el cursor automáticamente llamará al método * deactivate(), y cuando la activity se reinicie se llamrá al método

Page 87: Manual Inicio Android (1).pdf

 

  86  

* requery() para reiniciar el cursor. También nos ayudará al momento * en que la activity sea destruida el Cursor será cerrado automáticamente */ startManagingCursor(todo); String category = todo.getString(todo.getColumnIndexOrThrow(DBAdapter.KEY_CATEGORY)); for (int i = 0; i < mCategory.getCount(); i++) { String s = (String) mCategory.getItemAtPosition(i); Log.e(null, s + " " + category); if (s.equalsIgnoreCase(category)) { /* * Dependiendo de la categoria que haya sido registrada en la * BD, será entonces que en el Spinner sea seleccionada la misma * opción que se tenga en la BD * */ mCategory.setSelection(i); } } // Rellenamos los otros valores con lo que tengamos en la BD mTitleText.setText(todo.getString(todo .getColumnIndexOrThrow(DBAdapter.KEY_SUMMARY))); mBodyText.setText(todo.getString(todo .getColumnIndexOrThrow(DBAdapter.KEY_DESCRIPTION))); } } /* * En este método lo que se busca es que el id de la tarea sea * guardado con la intención de recuperarlo para cuando la activity * sea recreado * */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //saveState(); outState.putSerializable(DBAdapter.KEY_ROWID, mRowId); } @Override

Page 88: Manual Inicio Android (1).pdf

 

  87  

protected void onPause() { super.onPause(); //saveState(); } /* * Cuando la activity sea reiniciada mandará * ejecutar el método que rellena los campos * de la activity */ @Override protected void onResume() { super.onResume(); populateFields(); } /* * Sobreescribimos este método para que al presionar * el btón de back sea ejecutado el método de finish * */ @Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); finish(); } /* * Este método trata de guardar la información en la * BD * */ private void saveState() { String category = (String) mCategory.getSelectedItem(); String summary = mTitleText.getText().toString(); String description = mBodyText.getText().toString(); /* * Si la variable mRowId es nula entonces ejecutará el método crearNuevaTarea * para insertar los datos nuevos en la tabla, pero si no es null * entonces se ejecutará el método updateTarea para actualizar la información * de la tarea relacionada con el valor que tenga la variable mRowId * */ if (mRowId == null) { long id = mDbHelper.crearNuevaTarea(category, summary, description); if (id > 0) { mRowId = id;

Page 89: Manual Inicio Android (1).pdf

 

  88  

} } else { mDbHelper.updateTarea(mRowId, category, summary, description); } } }

Es  momento  de  realizar  otras  modificaciones,  es  turno  de  TareasFragment.java,  el  primero  y  que  es   muy   importante   es   cambiar   la   clase   de   la   cual   hereda,   en   este   momento   debería   de   estar  extendiendo  de  Fragment,  pero  ahora   vamos  a  modificarlo  por   ListFragment  esto   se  debe  a  que  esta  clase   muestra   una   lista   de   elementos   que   son   administrados   por   un   adaptador   (como   un  SimpleCursorAdapter),  similar  a  ListActivity.  Proporciona  varios  métodos  para  la  gestión  de  una  vista  de  lista,  como  la  devolución  de  llamada  onListItemClick  ()  para  gestionar  clic  eventos  sobre  la  lista,  esta  es  una  de  las  casusas  por  la  que  en  este  caso  heredaremos  de  esta  clase  (ListFragment).  Será  necesario  que  se  revise  el  código  que  se  muestra  a  continuación  pues  aquí  ya  se  muestran  todas  las  modificaciones  y  anexiones  que  se  le  hicieron  a  la  clase,  para  su  mayor  entendimiento  se  le  agregaron  varios  comentarios  para  que  sean  estudiados.  

import android.app.ListFragment; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.ContextMenu.ContextMenuInfo; import android.widget.ListView; import android.widget.SimpleCursorAdapter; import android.widget.AdapterView.AdapterContextMenuInfo; import com.android.utm.todosqlite.database.DBAdapter; public class TareasFragment extends ListFragment { private static final int ACTIVITY_CREATE = 0; private static final int ACTIVITY_EDIT = 1; private static final int DELETE_ID = Menu.FIRST + 1; private DBAdapter dbHelper; private Cursor cursor; public TareasFragment(){} @Override public View onCreateView(LayoutInflater inflater, ViewGroup

Page 90: Manual Inicio Android (1).pdf

 

  89  

container, Bundle savedInstanceState) { // TODO Auto-generated method stub View rootView = inflater.inflate(R.layout.activity_tareas, container, false); /** * Se crea una instancia de la clase DBAdapter, * el constructor de la clase mandará a crear la BD si no existe, * en caso de ya existir solo creará la conexión a la BD * */ dbHelper = new DBAdapter(getActivity().getApplicationContext()); // Abre la conexión a la BD dbHelper.open(); return rootView; } /* * Este método nos ayuda a saber cuando la * activity de nuestro fragment ha terminado de * ejecutar su método onCreate()*/ @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); fillData(); registerForContextMenu(getListView()); } /* * Se llama cada vez que se selecciona un elemento en un menú contextual * */ @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case DELETE_ID: AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo(); dbHelper.deleteTarea(info.id); fillData(); return true; } return super.onContextItemSelected(item); }

Page 91: Manual Inicio Android (1).pdf

 

  90  

//ListView y la acción al seleccionar un item /* * Este método se encarga de manejar los eventos de los * "clicks" en cada uno de los items de la lista * */ @Override public void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); /* * Al ser seleccionado uno de los elementos de la lista * se procede a armar un Intent que abrirá la activity * DetailsActivity.java para que se editen los valores. * Se manda un parámetro que es el id de la tarea a * editar*/ Intent i = new Intent(getActivity().getApplicationContext(), DetailsActivity.class); i.putExtra(DBAdapter.KEY_ROWID, id); //La actividad retorna un resultado cuando se llama //startActivityForResult startActivityForResult(i, ACTIVITY_EDIT); } /* * Crea los elementos del menú contextual * */ @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); menu.add(0, DELETE_ID, 0, R.string.menu_delete); } @Override public void onDestroy() { super.onDestroy(); if (dbHelper != null) { dbHelper.close(); } } /* * En este método se va a hacer una consulta a la BD en la * cual se van a recuperar todas las tareas que existan en * la BD, y estas luego serán agregadas al ListFragment. * */ private void fillData() { cursor = dbHelper.recuperaTodos(); getActivity().startManagingCursor(cursor);

Page 92: Manual Inicio Android (1).pdf

 

  91  

String[] from = new String[] { DBAdapter.KEY_SUMMARY }; int[] to = new int[] { R.id.label }; //Creamos un array adapter para desplegar cada una de las filas SimpleCursorAdapter notes = new SimpleCursorAdapter(getActivity().getApplicationContext(), R.layout.row, cursor, from, to); setListAdapter(notes); } }

 Por   último   hay   que   realizar   algunas   adecuaciones   a   la   clase   MainActivity.java,   estas  modificaciones     van   enfocadas   principalmente   en   agregar   la   funcionalidad   al   menú   “Insertar”,   este  menú  es  el  que  se  encarga  de  llamar  la  activity  DetailsActivity.java.  

Sólo  mostraré  el  método  que  hay  que  modificar  y  los  métodos  nuevos  que  irán  en  esta  clase.  

@Override public boolean onOptionsItemSelected(MenuItem item) { // Pasar el evento al ActionBarDrawerToggle, si este // regresa true, entonces este manejara el evento del touch // en el icono de la app if (mDrawerToggle.onOptionsItemSelected(item)) { Log.e("mDrawerToggle presionado", "x"); return true; }else{ switch (item.getItemId()) { case R.id.insertar: createTodo(); return true; } } // Maneja los otros items de la action bar... return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.tareas, menu); return true; } // Codificamos la accion al seleccionar el item del menu @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) {

Page 93: Manual Inicio Android (1).pdf

 

  92  

case R.id.insertar: createTodo(); return true; } return super.onMenuItemSelected(featureId, item); } private void createTodo() { Intent i = new Intent(this, DetailsActivity.class); startActivityForResult(i, ACTIVITY_CREATE); } //El siguiente metodo se llama con el resultado de otra actividad // requestCode es el codigo original que se manda a la actividad // resultCode es el codigo de retorno, 0 significa que todo saliÛ bien // intent es usado para obtener alguna informaciÛn del caller @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); //fillData(); //Cuando la aplicacion cargue por defecto mostrara la opcion Home MostrarFragment(1); }

 

Trazar  una  ruta  En   esta   sección   agregaremos   una   opción   nueva   a   nuestro   proyecto   de   ejemplo,   en   la   cual  aprovecharemos   para   explicar   como   crear   pestañas     y   swipe   en   la   aplicación,   además   de   explicar  algunas   cosas   relativas   a   los  mapas   (de  Google).   Este   ejemplo  mostrará   dos   opciones,   una   será   la   de  mostrar   el  mapa   con   la   ruta   trazada   dentro   de   la   aplicación   y   la   otra   será   lanzando   la   aplicación   de  “Maps  “  de  Google  para  que  nos  muestre  la  ruta,  bueno  manos  a  la  obra  lo  primero  que  hay  que  hacer  es  lo  que  se  indica  en  la  sección  Pasos  para  instalar  y/o  configurar  la  API  de  Google  Maps  Android.    

Ahora   será   necesario   agregar   los   permisos   de   para   poder   usar   el   GPS   del   celular   (para   una   mayor  referencia   para   el   uso   y/o   configuración   del   GPS   en   Android,   se   debería   de   estudiar   la   sección  Localización  geográfica  en  Android)  .  

En  este  punto  ya  deberíamos  de  tener  configurado  en  el  Manifest  del  proyecto  todos  los  permisos  para  la  recepción  de  mapas,  la  conexión  a  internet,  así  como  de  tener  ya  configurada  y  obtenida  nuestra  API  Key  de  Google  Maps,  por  lo  cual  procederemos  a  solicitar  los  permisos  para  poder  utilizar  la  localización  

Page 94: Manual Inicio Android (1).pdf

 

  93  

con   ayuda   del   GPS   o   de   la   red  WIFI,   por   lo   que   deberemos   de   agregar   los   siguientes   permisos   en   la  sección  de  permisos  del  Manifest:  

<!-- permite a la aplicación conocer la ubicación de manera "menos" precisa. Por ejemplo, utilizando WIFI. --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- permite a la aplicación que conozca de manera "precisa" la ubicación. Por ejemplo, utilizando GPS. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

por  lo  que  todo  nuestro  Manifest  quedará  como  se  muestra  a  continuación:  

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.utm.todosqlite" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="14" /> <permission android:name="com.android.utm.todosqlite.java.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="com.android.utm.todosqlite.java.permission.MAPS_RECEIVE" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <!-- permitimos abrir conexiones de red. --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- permite a la aplicación conocer la ubicación de manera "menos" precisa. Por ejemplo, utilizando WIFI. --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Page 95: Manual Inicio Android (1).pdf

 

  94  

<!-- permite a la aplicación que conozca de manera "precisa" la ubicación. Por ejemplo, utilizando GPS. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!—Le indicamos a nuestro celular que vamos a usar la versión OpenGL ES 2.0, esto es necesario para que el celular muestre de forma adecuada los mapas --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!—Declaración de la API Key para los mapas--> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyA7h1--xnFvHT1--Y3lTTof2FrtIp7MofY" /> <activity android:name="com.android.utm.todosqlite.MainActivity" android:label="@string/app_name" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.android.utm.todosqlite.TareasFragment" android:label="@string/title_activity_tareas" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.android.utm.todosqlite.MainActivity" /> </activity> <activity android:name="com.android.utm.todosqlite.DetailsActivity"

Page 96: Manual Inicio Android (1).pdf

 

  95  

android:windowSoftInputMode="stateVisible|adjustResize" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.android.utm.todosqlite.TareasFragment" /> </activity> <activity android:name="com.android.utm.todosqlite.TrazarRutaFragment" android:label="@string/title_activity_trazar_ruta" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.android.utm.todosqlite.MainActivity" /> </activity> </application> </manifest>

Como  se  podrá  notar  en  este  momento  ya  hay  varias  actividades  declaradas  pero  que  aún  no  las  hemos  codificado,   podemos   ir   adelantando   esto   para   que   no   se   nos   olvide  más   adelante,   o   si   lo   desean   al  momento   que   sean   declaradas   y/o   creadas   las   actividades   podríamos   venir   a   esta   sección   para  confirmar  la  manera  en  la  que  se  declaran,    

Nota  

Es  momento  de  recordar  que  todas  las  actividades,  fragments  (pantallas)  o  cualquier  tipo  de  View  que  se  muestre  en  la  pantalla  de  nuestro  móvil  debe  de  ser  declarado  en  el  Manifest  de  nuestro  proyecto,  de   lo   contrario   en   el  momento   que   deseemos   abrir   o  mostrarla   en   pantalla   la   aplicación   completa  fallará  y  se  cerrará.  

En  muchas  ocasiones  es  necesario  que  se  declare  un  nuevo  paquete  en  el  cual  se  colocan  ciertas  clases  que  se  pueden  considerar  individuales,  puesto  que  realizan  una  función  en  específico,  y  esta  función  en  muchos  de  los  casos  pueden  ser  usados  por  una  gran  cantidad  de  las  otras  clases,  a  este  tipo  de  clases  se   les   suele   llamar   que   son   utilerías,   y   lo   único   que   comparten   con   algunas   otras   clases   es   su  característica  de  ser  solas  o  únicas  por  lo  que  se  acostumbra  crear  un  paquete  con  terminación  util  para  nuestro   caso   será   el   siguiente: com.android.utm.todosqlite.util   (recordemos   que   estos  nombre  son  los  que  tengo  para  mi  proyecto,  deberían  de  usar  los  que  tengan  para  el  suyo,  no  tienen  por  qué   ser   iguales),   para   este   proyecto   vamos   a   tener   tres   clases   en   este   paquete   las   cuales   serán  Utils.java,   ConnectionDetecter.java   y   GMapsDirection.java   a   continuación  explicaré  a  grandes  rasgos  de  que  tratan  cada  una,  pero  cabe  mencionar  que  este  tipo  de  clases  pueden  reutilizarse   en   diferentes   proyectos   prácticamente   sin   ningún   tipo   de   modificación   salvo   pequeñas  adecuaciones  según  las  necesidades  especificas  de  algún  proyecto.  

Page 97: Manual Inicio Android (1).pdf

 

  96  

Utils.java  De   esta   clase   lo   que   nos   interesa   y   será   lo   único   que   explique   serán   los   métodos  AdjustWidthScreen() y AdjustHeightScreen(), el   primero   de   ellos   lo   que   hace   es  recibir  de  parámetros  el  alto,  ancho  de  un  elemento  view  de  un  layout  así  como  un  valor  que  representa  el   ancho   que   deseamos   que   tenga   el   objeto   con   respecto   a   la   pantalla,   este   valor   representa   el  porcentaje  del  ancho  de  la  pantalla  y  también  se  recibe  como  parámetro,    el  último  parámetro  recibido  es  el  objeto  al  cual  queremos  calcular  el  ancho.  El  segundo  hace  lo  mismo  pero  en  el  alto  del  elemento  recibido  como  parámetro.  Aquí  presento  el  código  que  tendrá  esta  clase:  

package com.android.utm.todosqlite.util; import android.annotation.TargetApi; import android.os.Build; import android.os.StrictMode; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; /** * Class containing some static utility methods. */ public class Utils { public Utils() {}; @TargetApi(11) public static void enableStrictMode() { if (Utils.hasGingerbread()) { StrictMode.ThreadPolicy.Builder threadPolicyBuilder = new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog(); StrictMode.VmPolicy.Builder vmPolicyBuilder = new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog(); StrictMode.setThreadPolicy(threadPolicyBuilder.build()); StrictMode.setVmPolicy(vmPolicyBuilder.build()); } } public static boolean hasFroyo() { // Can use static final constants like FROYO, declared in later versions // of the OS since they are inlined at compile time. This is guaranteed behavior.

Page 98: Manual Inicio Android (1).pdf

 

  97  

return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO; } public static boolean hasGingerbread() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; } public static boolean hasHoneycomb() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; } public static boolean hasHoneycombMR1() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1; } /** * Este método nos ayuda a ajustar el ancho * de algunos tipos de elementos pero dado * un porcentaje con relación a la pantalla * */ public void AdjustWidthScreen(int width, int height, int percent, Object theObject) { if (theObject instanceof TextView) { ((TextView) theObject).setWidth((percent * width) / 100); } else if (theObject instanceof LinearLayout) { ((LinearLayout) theObject).setMinimumWidth((percent * width) / 100); } else if (theObject instanceof Button) { ((Button) theObject).setHeight((percent * width) / 100); } else if (theObject instanceof ImageView) { ((ImageView) theObject).getLayoutParams().width = ((percent * width) / 100); } else { return; } return; } /** * Este método nos ayuda a ajustar el alto * de algunos tipos de elementos pero dado * un porcentaje con relación a la pantalla * */ public void AdjustHeightScreen(int width, int height, int

Page 99: Manual Inicio Android (1).pdf

 

  98  

percent, Object theObject){ if (theObject instanceof TextView) { ((TextView) theObject).setHeight((percent * height) / 100); } else if (theObject instanceof LinearLayout){ ((LinearLayout) theObject).setMinimumHeight((percent * height) / 100); } else if (theObject instanceof Button){ ((Button) theObject).setHeight((percent * height) / 100); } else if (theObject instanceof ImageView){ ((ImageView) theObject).getLayoutParams().height = (percent * height) / 100; } return; } }  

ConnectionDetecter.java  Esta  clase  es  muy  simple,  de  lo  único  que  se  encarga  es  de  detectar  si  hay  conexión  a  internet,  regresa  un  valor  boolean,  si  hay  conexión  retorna  true,  en  caso  contrario  false,  veamos  el  código  de  dicha  clase.  

package com.android.utm.todosqlite.util; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; public class ConnectionDetector { private Context context; public ConnectionDetector(Context context){ this.context = context; } /** * Revisa todos los posibles proveedores de internet * en pocas palabras se encarga de revisar si tenemos * conexión a internet en el dispositivo * **/ public boolean isConnectedToInternet(){ ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

Page 100: Manual Inicio Android (1).pdf

 

  99  

NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting(); return isConnected; } }

GMapsDirection.java  Esta  clase  es  un  poco  más  complicada,  pues  realiza  más  cosas,  en  este  caso  debemos  de  mencionar  y  tener  mucho  cuidado  pues  esta  clase  está  enfocada  en  un  mapa  que  está  siendo  renderizado  sobre  un  Fragment,  en  el  caso  de  que  sea  otro  tipo  de  View  en  el  cual  se  esté  mostrando  se  deberan  de  tomar  las  medidas  pertinentes  para  asegurarse  que  este  funcione  adecuadamente.  

Empezaremos  diciendo  que  en  el  constructor  recibe  como  parámetro  el  fragment  sobre  el  cual  se  está  ejecutando  o  mostrando  el  mapa   y   sobre   el   cual   se   va   a   pintar   la   ruta   de  nuestro   punto  de  origen   a  nuestro  punto  de  destino.  

En  el  método  getDocument()armamos  la  url  de  petición  a  Google  donde  le  pedimos  que  nos  de  las  indicaciones  de  cómo  llegar  desde  nuestro  punto  de  origen  hasta  nuestro  punto  de  destino,  para  lo  cual  necesitamos  las  coordenadas  de  inicio  y  de  destino  es  aquí  donde  antes  de  iniciar  el  proceso  asíncrono  de   consultar   a   Google,   donde   hacemos   la   verificación   de   conexión   a   internet   con   ayuda     de   la   clase  ConnectionDetector(),  si  tenemos  conexión  iniciamos  la  consulta,  si  no,  no  se  realiza  la  consulta.  

Dentro  de  esta  clase  tenemos  una  clase  interna  que  hereda  de  la  clase  AsyncTask,  la  cual  recibe  la  url  de   petición   para   Google   y   entrega   un   objeto   del     tipo   Document   el   cual   contiene   los   pasos   y  coordenadas  de   los   puntos  para   llegar   al   destino   especificado,   ahora   en   esta  otra   clase   tenemos   tres  métodos   que   sobreescribiremos   el   primero   se   llama   onPreExecute   en   este   método   lo   único   que  haremos  será  iniciar  un  PogressDialog,  este  estará  visible  mientras  se  ejecuta  el  proceso  de  preguntar  a  Google   y  de  que  de   su   respuesta   y  así  mismo  de   trazar   la   ruta   sobre  el  mapa.  El   segundo  método  es  doInBackGroound, este  método  recibe  como  parámetro  la  url  para  realizar  la  consulta  a  Google,  y  como  resultado  de  su  ejecución  dará  un  objeto  del   tipo  Document  el  cual  contendrá   la  estructura  del  documento   XML   que   responde   Google   y   que   contiene   la   información   de   cómo   llegar.   Ya   por   último  tenemos  al  método  doPostExecute,  este  método  recibe  el  objeto  Document  con  la  información  del  XML  de  respuesta  de  Google.  Otro  método  que  tenemos  en  esta  clase  es  el  método  getDirection  y  este  método   recibe  el  obejto  Document  con   toda   la   información  del  XML  de  Google  y   lo  que  hace  es  obtener  la  información  contenida  en  él  para  obtener  únicamente  los  puntos  con  sus  coordenadas  y  que  serán  puestos  en  el  mapa  para  representar  la  ruta,  así  mismo  tenemos  los  métodos  getNodeIndex  y  decodePoly   pero   estos   métodos   son   auxiliares   del   getDirection.   Y   ya   para   terminar   aquí   m  uestro  la  clase  completa:  

package com.android.utm.todosqlite.util; import java.io.InputStream; import java.util.ArrayList;

Page 101: Manual Inicio Android (1).pdf

 

  100  

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import android.app.ProgressDialog; import android.os.AsyncTask; import com.android.utm.todosqlite.TrazarRutaInternaFragment; import com.google.android.gms.maps.model.LatLng; public class GMapsDirection { public final static String MODE_DRIVING = "driving"; public final static String MODE_WALKING = "walking"; private TrazarRutaInternaFragment fragment; public ProgressDialog progress; /** * El constructor recibe como parámetro * el fragment sobre el cual se está ejecutando * o mostrando el mapa y sobre el cual se va a * pintar la ruta de nuestro punto de origen a * nuestro punto de destino * */ public GMapsDirection(TrazarRutaInternaFragment fragment) { this.fragment = fragment; } public void getDocument(LatLng start, LatLng end, String mode) { /** * Armamos la url de petición a Google * donde le pedimos que nos de las indicaciones * de cómo llegar desde nuestro punto de origen * hasta nuestro punto de destino, para lo cual * necesitamos las coordenadas de inicio y de * destino * */ String url = "http://maps.googleapis.com/maps/api/directions/xml?" + "origin=" + start.latitude + "," + start.longitude + "&destination=" + end.latitude + "," + end.longitude

Page 102: Manual Inicio Android (1).pdf

 

  101  

+ "&sensor=false&units=metric&mode="+MODE_DRIVING; // Usamos nuestra clase ConnectionDetector para verificar la conectividad a internet ConnectionDetector connectionDetector = new ConnectionDetector(fragment.getActivity()); if(connectionDetector.isConnectedToInternet()){ new RetrieveData().execute(url); } } /** * Clase interna que hereda de AsyncTask la cual recibe * la url de petición para Google y entrega un objeto del * tipo Document el cual contiene los pasos y coordenadas * de los puntos para llegar al destino especificado * */ class RetrieveData extends AsyncTask<String, Void, Document> { /** * En este método lo único que haremos será iniciar * un PogressDialog, este estará visible mientras * se ejecuta el proceso de preguntar a Google y de * que de su respuesta y así mismo de trazar la ruta * sobre el mapa * */ @Override protected void onPreExecute() { progress = new ProgressDialog(fragment.getActivity()); progress.setTitle("Cargando"); progress.setMessage("Por favor, espera..."); progress.setCanceledOnTouchOutside(false); progress.show(); } /** * Este método recibe como parámetro la url para realizar * la consulta a Google, y como resultado de su ejecución * dará un objeto del tipo Document el cual contendrá la * estructura del documento XML que responde Google y que * contiene la información de cómo llegar * */ protected Document doInBackground(String... urls) { try { // Interfaz para un cliente HTTP. HttpClient httpClient = new DefaultHttpClient();

Page 103: Manual Inicio Android (1).pdf

 

  102  

// Un contexto para la ejecución de una solicitud. HttpContext localContext = new BasicHttpContext(); // El método POST se utiliza para solicitar que el servidor de origen acepte la entidad incluida en la solicitud HttpPost httpPost = new HttpPost(urls[0]); /** * Los clientes HTTP encapsulan una mezcla heterogénea de objetos * necesarios para ejecutar solicitudes HTTP al manipular las cookies, * autenticación, gestión de la conexión, y otras características. * */ HttpResponse response = httpClient.execute(httpPost, localContext); // Se genera un objeto InputStream donde se almacena la respuesta de Google InputStream in = response.getEntity().getContent(); //Instanciamos la fábrica para DOM y creamos el nuevo parser DOM DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); // Realizamos la lectura completa del XML Document doc = builder.parse(in); return doc; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Este método recibe el objeto Document con la información * del XML de respuesta de Google * */ protected void onPostExecute(Document document) { if(document != null){ /** * Ejecutamos el método de traceRoute * que pertenece a la clase TrazarRutaInternaFragment * y se pasa de parámetro el objeto Document*/ fragment.traceRoute(document); }

Page 104: Manual Inicio Android (1).pdf

 

  103  

// Ocultamos el ProgressDialog progress.hide(); } } /** * Este método recibe el obejto Document con toda * la información del XML de Google * y lo que hace es obtener la información contenida * en él para obtener únicamente los puntos con sus * coordenadas y que serán puestos en el mapa para * representar la ruta * */ public ArrayList<LatLng> getDirection(Document doc) { NodeList nl1, nl2, nl3; ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>(); nl1 = doc.getElementsByTagName("step"); if (nl1.getLength() > 0) { for (int i = 0; i < nl1.getLength(); i++) { Node node1 = nl1.item(i); nl2 = node1.getChildNodes(); Node locationNode = nl2 .item(getNodeIndex(nl2, "start_location")); nl3 = locationNode.getChildNodes(); Node latNode = nl3.item(getNodeIndex(nl3, "lat")); double lat = Double.parseDouble(latNode.getTextContent()); Node lngNode = nl3.item(getNodeIndex(nl3, "lng")); double lng = Double.parseDouble(lngNode.getTextContent()); listGeopoints.add(new LatLng(lat, lng)); locationNode = nl2.item(getNodeIndex(nl2, "polyline")); nl3 = locationNode.getChildNodes(); latNode = nl3.item(getNodeIndex(nl3, "points")); ArrayList<LatLng> arr = decodePoly(latNode.getTextContent()); for (int j = 0; j < arr.size(); j++) { listGeopoints.add(new LatLng(arr.get(j).latitude, arr .get(j).longitude)); } locationNode = nl2.item(getNodeIndex(nl2, "end_location")); nl3 = locationNode.getChildNodes();

Page 105: Manual Inicio Android (1).pdf

 

  104  

latNode = nl3.item(getNodeIndex(nl3, "lat")); lat = Double.parseDouble(latNode.getTextContent()); lngNode = nl3.item(getNodeIndex(nl3, "lng")); lng = Double.parseDouble(lngNode.getTextContent()); listGeopoints.add(new LatLng(lat, lng)); } } return listGeopoints; } private int getNodeIndex(NodeList nl, String nodename) { for (int i = 0; i < nl.getLength(); i++) { if (nl.item(i).getNodeName().equals(nodename)) return i; } return -1; } private ArrayList<LatLng> decodePoly(String encoded) { ArrayList<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5); poly.add(position); } return poly;

Page 106: Manual Inicio Android (1).pdf

 

  105  

} }  

Ahora   es   momento   ya   de   empezar   a   trabajar   la   parte   que   será   visible   en   nuestra   aplicación,  empezaremos   con   el   diseño   de   los   layouts   de   las   interfaces   de   cada   uno   de   los   fragments   que  aparecerán   en   nuestras   pestañas,   a   continuación  muestro   una   captura   de   pantalla   de   cómo   se   vería  nuestra  aplicación  al  terminar:  

 

Lo  que  vemos  es  una  pantalla  que  tiene  dos  tabs,  en  una  tenemos  un  mapa  con  una  ruta  marcada  sobre  de   él,   y   en   la   otra   pestaña   es   un   pequeño   formulario   en   el   cual   vemos   unos   parametros   con   las  posiciones  actuales  y  la  de  destino  y  un  botón,  la  pantalla  se  ve  así  por  que  en  el  momento  de  tomar  la  captura   de   pantalla   se   está   haciendo   un   swipe   entre   las   pestañas,   es   decir   esta   aplicación   tiene   un  ViewPager.  

Creación  de  elementos  visuales  En   esta   sección   nos   dedicaremos   a   sólo   crear   todo   los   layouts   y/o   archivos   de   configuración   que  necesitemos  para  la  creación  de  nuestra  aplicación  

Procederemos   ahora   a   crear   los   diferentes   layouts,   el   primero   que   crearemos   se   llamará  como_llegar_interna_fragment.xml,  dicho  layout  pertenece  al  fragment  que  nos  mostrará  la  ruta   de   cómo   llegar   entre   dos   puntos   directamente   en   el  mapa,   es  muy   simple,   se   ocupa   un   view   o  elemento  en  el  cual  se  muestra  un  mapa     (con   los  datos  obtenidos  del  servicio  de  Google  Maps).  Una  vez   enfocado,   capturará   las   pulsaciones   de   teclas   y   gestos   táctiles   para   mover   el   mapa.   También  

Page 107: Manual Inicio Android (1).pdf

 

  106  

contiene  un    ImageView  que  tiene  el  atributo  visibility  en  invisible  esto  es  un  truco  que  se  necesita  para  poder  hacer  swipe  entre   las  pestañas,  de  no  ser  así  en  algunas  versiones  nuevas  de  Android  mostrará  unas  secciones  en  negro  al  momento  de  cambiar  las  pestañas,  si  su  aplicación  no  ocupa  hacer  swipe  con  el  mapa,  entonces  no  es  necesario  que  tenga  el  ImageView.  Este  es  el  código:  

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- Un view que muestra un mapa (con los datos obtenidos del servicio de Google Maps). Una vez enfocado, capturará las pulsaciones de teclas y gestos táctiles para mover el mapa. --> <com.google.android.gms.maps.MapView android:id="@+id/mapa" android:layout_width="match_parent" android:layout_height="match_parent" map:uiZoomControls="true" /> <!-- Este ImageView tiene el atributo visibility en invisible esto es un truco que se necesita para poder hacer swipe entre las pestañas, de no ser así en algunas versiones nuevas de Android mostrará unas secciones en negro al momento de cambiar las pestañas--> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="invisible" /> </RelativeLayout>

Para  el  layout  de  la  otra  pestaña  que  lo  que  hace  es  pedir  a  una  aplicación  externa  que  muestre  el  trazo  de  la  ruta  que  se  desea,  para  este  caso  se  desea  sea  mostrada  por    a  aplicación  Maps  de  Google,  pero  en  muchos   casos  podría  pasar  que  existan  varias  aplicaciones  que  puedan  abrir   la   ruta   solicitida   (es  algo  complicado   especificar   una   aplicación   en   especial),   en   ese   caso   lo   que   hace   android   de   forma  automática  es  algo  como  lo  que  se  muestra  en  la  imagen  de  siguiente:  

Page 108: Manual Inicio Android (1).pdf

 

  107  

 

En  este  caso  ya  es  decisión  personal  que  opción  tomar,  pero  yo  aconsejo  hacerlo  con   la  aplicación  de  Maps,  ya  que  nos  dará  como  resultado  lo  que  vemos  en  las  siguientes  imágenes:    

                                                                           

Page 109: Manual Inicio Android (1).pdf

 

  108  

El  segundo  layout  será  demasiado  simple  pues  los  elementos  que  utilizaremos  son  varios  que  ya  hemos  usado   varias   veces   en   otros   ejemplos,   pero   aquí   dejo   el   código   como   ejemplo,   el   layout   se   llamará  como_llegar_externa_fragment.xml:  

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:background="#CECECE" > <TextView android:id="@+id/latitud_origen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/longitud_origen" android:layout_below="@+id/longitud_origen" android:layout_marginTop="28dp" android:text="Latitud Origen" /> <TextView android:id="@+id/longitud_origen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="18dp" android:layout_marginTop="16dp" android:text="Longitud Origen" /> <!-- Aquí se va a mostrar la longitud de origen obtenida del GPS del móvil --> <TextView android:id="@+id/longitud_origen_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/latitud_origen" android:layout_centerHorizontal="true" android:text="TextView" /> <!-- Aquí se va a mostrar la latitud de origen obtenida del GPS del móvil --> <TextView android:id="@+id/latitud_origen_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/latitud_origen" android:layout_alignLeft="@+id/longitud_origen_txt" android:text="TextView" />

Page 110: Manual Inicio Android (1).pdf

 

  109  

<TextView android:id="@+id/longitud_destino" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/latitud_origen" android:layout_below="@+id/latitud_origen" android:layout_marginTop="27dp" android:text="Longitud Destino" /> <!-- Aquí se muestra la longitud de destino --> <TextView android:id="@+id/longitud_destino_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/longitud_destino" android:layout_alignBottom="@+id/longitud_destino" android:layout_alignLeft="@+id/latitud_origen_txt" android:text="-99.131111" /> <TextView android:id="@+id/latitud_destino" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/longitud_destino" android:layout_below="@+id/longitud_destino" android:layout_marginTop="24dp" android:text="Latitud Destino" /> <!-- Aquí se muestra la latitud de destino --> <TextView android:id="@+id/latitud_destino_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/latitud_destino" android:layout_alignBottom="@+id/latitud_destino" android:layout_alignLeft="@+id/longitud_destino_txt" android:text="19.4325" /> <!-- Botón que realizará el proceso de armar la URL para solicitar el trazado de la ruta de un punto de origen a uno de destino --> <Button android:id="@+id/btn_trazar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/latitud_destino_txt" android:layout_centerHorizontal="true" android:layout_marginTop="86dp" android:text="Trazar Ruta" /> </RelativeLayout>

Page 111: Manual Inicio Android (1).pdf

 

  110  

En  nuestro  ejemplo  las  pestañas  tendrán  dos  colores,  una  para  cuando  están  seleccionados  (#558e33),  y  otro  para  cuando  no  lo  están  (#adab21),  es  por  esta  razón  que  registraremos  dos  colores  en  el  archivo  colors.xml,  además  también  registraremos  un  color  para  la  línea  a  trazar  de  la  ruta  en  el  mapa,  por  lo  que  nuestro  archivo  de  configuración  de  colores  quedará  cómo  se  muestra  en  el  listado  siguiente:  

<?xml version="1.0" encoding="utf-8"?> <resources> <color name="list_color">#94A65D</color> <color name="negro">#000000</color> <!-- Estos son las tres nuevas definiciones de colores --> <color name="tab_trazar_on">#558e33</color>

<color name="tab_trazar_off">#adab21</color> <color name="route">#65b4f1</color> </resources> Android   tiene   una   forma   muy   fácil   para   controlar   el   estilo   de   los   elementos   que   deben   de   mostrar  cuando  sean  tocados,  seleccionados  o  enfocados  entre  otros.  Para   lograr  que  de  forma  automática  se  cambién   los  colores  de   las  pestañas  será  necesario  crear  un  nuevo  archivo  xml  pero  este  estará  en   la  carpeta  drawable  y  llevará  por  nombre  tab_selector_trazar.xml,  en  este  archivo  se  declararán  las  reglas  que  se  deben  de  cumplir  cada  vez  que  una  de  las  pestañas  es  tocada  o  cada  vez  que  su  estado  cambie   ha   seleccionado,   a   continuación   se   muestra   el   código   de   este   archivo   (en   lugar   de   colores  pueden  ser  definidas  imágenes):  

<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <!-- Active tab --> <!-- Lo que se dice aquí es que cuando el estado de seleccionado de una tab sea verdadero se deberá de aplicar a la pestaña el color definido con el nombre tab_trazar_on --> <item android:drawable="@color/tab_trazar_on" android:state_selected="true"/> <!-- Inactive tab --> <!-- Lo que se dice aquí es que cuando una tab no esté seleccionado se deberá de aplicar a la pestaña el color definido con el nombre tab_trazar_off --> <item android:drawable="@color/tab_trazar_off"/> </selector>  

Si  no  queremos  que  las  pestañas  de  nuestra  aplicación  luzcan  de  la  forma  por  default  como  en  el  estilo  de  Android   será  necesario  que  sea  creado  un   layout  nuevo  en  donde  se  especifique  el  nuevo  estilo  o  apariencia,   como  ese  es  el   caso  del  proyecto  que  estamos  desarrollando  entonces  será  necesario  que  sea   creado   un   nuevo   layout   de   nombre  tab_layout_trazar.xml, este   nuevo   diseño   es   muy  simple  consta  de  un  RelativeLayout  al  cual  le  aplicaremos  como  valor  del  atributo  background  el  archivo  

Page 112: Manual Inicio Android (1).pdf

 

  111  

previamente  creado,  esto  hará  que  si   la  pestaña  está  seleccionada  tenga  un  color  y  si  no  lo  está  tenga  otro  color,  el  otro  elemento  que  aparecerá  es  un  TextView  en  el  cual  aparecerá  el  texto  que  deseemos  en   cada   pestaña.   Este   layout   será   aplicado   a   cada   una   de   las   pestañas   que   tengamos   en   pantalla   al  momento,  este  es  el  código  del  layout:  

<?xml version="1.0" encoding="utf-8"?> <!-- Lo interesante en este caso es la aplicación en el atributo background del archivo tab_selector_trazar.xml para cambiarle los colores según el status de la pestaña --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/tab_selector_trazar" > <TextView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#FFF" android:gravity="center" android:layout_centerInParent="true" /> </RelativeLayout>

Ya  definimos   como  se  debe  de  ver   cada  una  de   las  pestañas  que  deberá  de   tener  nuestra  aplicación,  ahora  vamos  a  definir   la  estructura  completa,  ¿esto  qué  significa?,  pues  definir  mediante  un   layout   la  ubicación  de  donde  deben  de  aparecer  las  pestañas  (tabs),  la  cantidad  de  pestañas  a  mostrar,  definir  un  espacio  para  que  sean  mostrados  los  contenidos  de  cada  pestaña,  y  en  el  caso  de  este  ejemplo  agregar  el  elemento  de  ViePager  para  poder  hacer  el  movimiento  de  swipe  entre  pestañas.  Comenzaremos  por  definir  un  elemento  TabHost  el  cual  es  un  contenedor  para  las  pestañas  en  una  ventana,  este  contiene  dos  hijos,  uno  es  el  un  conjunto  de  etiquetas  para  las  pestañas  que  el  usuario  hace  clic  para  seleccionar  una  pestaña  específica,  el  otro  hijo  es  un  objeto  FrameLayout  el  cual  muestra  el  contenido  de  la  página.    El  siguiente  elemento  importante  es  el  TabWidget,  y  es  aquí  donde  se  muestran  las  pestañas  de  nuestro  proyecto,   en   la   sección   donde   salen   el   FrameLayout   es   en   donde   tendremos   un   FrameLayout   para  mostrar  el  contenido  de  cada  layout  que  deseemos  mostrar.    A  continuación  se  presenta  el  código  que  se  utilizaría  para  nuestro   caso,   este   layout   sería  un  gran  ejemplo  para  otras   vistas   con  pestañas  pues  debe  de   llevar   todos   los  elementos  que   se  muestran  en  el   código,   el  único  que  no  es  necesario  es  el  ViewPager  pues  es  un  agregado  para  darle  la  funcioanlidad  del  Pager  a  nuestro  ejemplo.  

<?xml version="1.0" encoding="utf-8"?> <!-- Contenedor para las pestañas en una ventana, este contiene dos hijos, uno es el un conjunto de etiquetas para las pestañas que el usuario hace clic para seleccionar una pestaña específica, el otro hijo es un objeto FrameLayout el cual muestra el contenido de la página -->

Page 113: Manual Inicio Android (1).pdf

 

  112  

<TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabhost_trazar" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@null" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- Aquí será la sección de las pestañas y siempre el id deberá de tener el valor de android:id="@android:id/tabs" --> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="top" android:tabStripEnabled="false" > </TabWidget> <!-- contenedor para el contenido de las pestañas con el id obligatorio "@android:id/tabcontent" --> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="0dp" android:background="@null" > <!-- Por cada pestaña que contenga la vista se deberá de incluir un FrameLayout --> <FrameLayout android:id="@+id/tab_1_interna" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <FrameLayout android:id="@+id/tab_2_externa" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </FrameLayout> <!-- Controlador que que permite al usuario mover de un tirón a la izquierda y derecha a tráves de diferentes ventanas --> <android.support.v4.view.ViewPager android:id="@+id/pager_trazar_ruta" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" />

Page 114: Manual Inicio Android (1).pdf

 

  113  

</LinearLayout> </TabHost>

Para  terminar  con  la  fase  de  diseño  de  interfaz  será  necesario  tener  un  layout  en  el  cual  tengamos  un  concentrador  de   todos   los   demás   layouts   hechos  pues   son  esos   layouts   una  parte  del   diseño   general  dicho   layout   se   llamará  fragment_trazar.xml que   en   verdad   es   demasiado   sencillo   su   diseño  pues   solo   tiene   un   LinearLayout   como   contenedor   principal   pero   es   aquí   en   donde   se   usa   un   nuevo  elemento,  se  llama  include  y  de  lo  que  se  encarga  o  para  lo  que  sirve  es  para  incluir  un  layout  dentro  de  otro  sólo  es  necesario  usar  el  atributo  layout  y  especificarle  el  nombre  del  layout  a  incluir.  Para  caso  de  nuestro  ejemplo  mostramos  el  siguiente  código  que  ilustrará  de  mejor  manera  lo  que  se  dice:  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#12ac56" android:orientation="vertical" android:baselineAligned="false" > <!-- El elemento include nos sirve para incluir otros layouts dentro de este sólo basta con indicar el nombre del layout a incluir --> <include android:layout_width="wrap_content" android:layout_height="0dip" android:layout_weight="1" layout="@layout/view_tabs_layout_trazar" /> </LinearLayout> Por  fin  se  ha  terminado  la  fase  de  diseño  de  la  interfaz  es  necesario  ahora  entrar  al  código  en  java  para  poder   agregar   la   funcionalidad   necesaria   para   que   nuestra   aplicación   funcione   de   la   mejor   manera  posible.  

 

 

 

 

     

 

 

Page 115: Manual Inicio Android (1).pdf

 

  114  

 

Adapters  Los   Adapters   de   Android   son   un   puente   entre   el   Adapter   View   (por   ejemplo   ListView)   y   los   datos  subyacentes  para  esa  vista.  Imagínese  lo  que  hubiera  sido  el  mundo  sin  necesidad  de  adaptadores!  

Sin  Adapters,  para  implementar  la  funcionalidad  del  ListView,  se  habría  necesitado  de:  

• Crear  un  TextView  dentro  de  un  ScrollView.  • Tendriamos  que  poner  en  práctica  el  concepto  de  paginación  de  los  contenidos  del  TextView.  • Tendríamos  que  escribir  código  adicional  para  identificar  el  evento  del  “click”  en  una  fila  en  

particular  el  TextView  

A  continuación  se  muestra  un  diagrama  conceptual  de  alto  nivel  que  muestra  el  trabajo  del  adaptador  de  Android:  

 

Entender  el  comportamiento  interno  de  un  Android  Adapter  

Los  Adapters   llaman  al  método  getView()  que  devuelve  una  vista  para  cada  elemento  dentro  de   la  vista  del  adaptador.  El  método  de  formato  del  layout  y  los  datos  correspondientes  a  un  elemento  dentro  de   la   vista   del   adaptador   se   encuentra   en   el   getView(). Ahora,   esto   sería   una   pesadillacon   el    rendimiento  si  getView()  devuelve  una  nueva  vista  cada  vez  que  se   le   llama.  Crear  una  nueva  vista  sería  muy  caro  en  Android,  ya  que  se  necesitaría  para  recorrer  la  jerarquía  de  vistas  (usando  el  método  ViewbyID()  para  encontrar)  y  luego  inflar  la  vista  para  finalmente  mostrarlo  en  la  pantalla.  Esto  pone  mucha  presión  sobre  el  recolector  de  basura.  Así  que  lo  que  Android  hace  es  que  recicla  y  reutiliza  las  vistas  que  están   fuera  de   foco.  Abajo   se  muestra  un   representación  visual  de   lo  que  es  el  proceso  de  reciclado:  

Page 116: Manual Inicio Android (1).pdf

 

  115  

 

En  la  figura  anterior,  asumimos  que  estamos  viendo  los  meses  en  un  año  en  un  ListView.  Para  empezar,  los  meses  de  enero  a  mayo  se  muestran  en  la  pantalla.  Al  desplazarse  por  la  vista,  el  mes  de  enero  se  sale  de   la  zona  de  visualización  de   la  pantalla  del  móvil.  Tan  pronto  como   la  vista  de  enero  sale  de   la  pantalla,  el  Adapter  View  (ListView  en  este  caso)  envía  la  vista  a  algo  que  se  llama  un  reciclador.  Así  que  cuando  se  desplaza  hacia  arriba,  el  método  getView()  se  llama  para  obtener  el  siguiente  punto  de  vista  (que  es  de  junio).  Este  método  getView()  tiene  un  parámetro  llamado  convertview  que  apunta  a  la  vista  sin  utilizar  en  el  reciclador.  A  través  del  convertview,  el  adaptador  intenta  controlar  la  vista  sin  usar  y  reutilizarla  para  mostrar  la  nueva  vista  (que  es  de  junio,  en  este  caso).  

Mapas  en  Android  (Google  Maps  Android  API  v2)  Esta  versión  presenta  muchas  novedades  interesantes,  de  las  que  cabe  destacar  las  siguientes:  

• Integración  con  los  Servicios  de  Google  Play  (Google  Play  Services)  y  la  Consola  de  APIs.  • Utilización  a   través  de  un  nuevo  tipo  específico  de   fragment   (MapFragment),  una  mejora  muy  

esperada  por  muchos.  • Utilización  de  mapas  vectoriales,  lo  que  repercute  en  una  mayor  velocidad  de  carga  y  una  mayor  

eficiencia  en  cuanto  a  uso  de  ancho  de  banda.  • Mejoras  en  el  sistema  de  caché,  lo  que  reducirá  en  gran  medida  las  famosas  áreas  en  blanco  que  

tardan  en  cargar.  • Los  mapas   son   ahora   3D,   es   decir,   podremos  mover   nuestro   punto   de   vista   de   forma   que   lo  

veamos  en  perspectiva.  

Pasos  para  instalar  y/o  configurar  la  API  de  Google  Maps  Android.  

1. En  primer  lugar,  dado  que  la  API  v2  se  proporciona  como  parte  del  SDK  de  Google  Play  Services,  será  necesario  incorporar  previamente  a  nuestro  entorno  de  desarrollo  dicho  paquete.  Haremos  esto  accediendo  desde  Eclipse  al  Android  SDK  Manager  y  descargando  del  apartado  de  extras  el  paquete  llamado  “Google  Play  Services”.  

Page 117: Manual Inicio Android (1).pdf

 

  116  

 

Imagen  33  

Tras   pulsar   el   botón   de   Install   y   aceptar   la   licencia   correspondiente   el   paquete   quedará   instalado   en  nuestro   sistema,   concretamente   en   la   ruta:   <carpeta-sdk-

android>/extras/google/google_play_services/.   Recordemos   esto   porque   nos   hará  falta  más  adelante.  

2. El  siguiente  paso  será  obtener  una  API  Key  para  poder  utilizar  el  servicio  de  mapas  de  Google  en  nuestra  aplicación.  

3. La  nueva  API  de  mapas  de  Android  se  ha  integrado  por  fin  en  la  Consola  de  APIs  de  Google,  por  lo  que  el  primer  paso  será  acceder  a  ella.    

4. Es   probable   que   si   nunca   hemos   entrado   a   la   consola   de   APIS   de   Google   nos   pida   que   una  pantalla  como  la  que  se  muestra  a  continuación,  por  lo  que  hacemos  click  en  el  botón  “Create  Proyect…”,  en  caso  de  no  ser  así  continuamos  con  el  punto  5  directamente.  

Page 118: Manual Inicio Android (1).pdf

 

  117  

 

Imagen  34  

5. Una   vez   hemos   accedido,   tendremos   que   crear   un   nuevo   proyecto   desplegando   el   menú  superior  izquierdo  y  seleccionando  la  opción  “Create…”.    

 

Imagen  35  

6. Aparecerá  entonces  una  ventana  que  nos  solicitará  el  nombre  del  proyecto.  Introducimos  algún  nombre  descriptivo  y  aceptamos  sin  más.  

 

Imagen  36  

7. Una  vez  creado  el  proyecto,  accederemos  a  la  opción  “Services”  del  menú  izquierdo.  Desde  esta  ventana   podemos   activar   o   desactivar   cada   uno   de   los   servicios   de   Google   que   queremos  

Page 119: Manual Inicio Android (1).pdf

 

  118  

utilizar.   En   este   caso   sólo   activaremos   el   servicio   llamado   “Google   Maps   Android   API   v2″₺  pulsando  sobre  el  botón  ON/OFF  situado  justo  a  su  derecha.  

 

Imagen  37  

8. Ahora  aceptamos  los  términos  de  uso  de  Google.  

 

Imagen  38  

9. Una   vez   activado   aparecerá   una   nueva   opción   en   el   menú   izquierdo   llamada   “API   Access”.  Accediendo  a  dicha  opción  tendremos  la  posibilidad  de  obtener  nuestra  nueva  API  Key  que  nos  permita  utilizar  el  servicio  de  mapas  desde  nuestra  aplicación  particular.  

Page 120: Manual Inicio Android (1).pdf

 

  119  

 

Imagen  39  

 

10. Para   ello,   pulsaremos   el   botón   “Create   new   Android   key…”.   Esto   nos   llevará   a   un   cuadro   de  diálogo  donde  tendremos  que  introducir  algunos  datos  identificativos  de  nuestra  aplicación.  En  concreto   necesitaremos   dos:   la   huella   digital   (SHA1)   del   certificado   con   el   que   firmamos   la  aplicación,   y  el  paquete   java  utilizado.  El   segundo  no   tiene  misterio,  pero  el  primero   requiere  alguna  explicación.    Toda   aplicación  Android   debe   ir   firmada   para   poder   ejecutarse   en   un   dispositivo,   tanto   físico  como   emulado.   Este   proceso   de   firma   es   uno   de   los   pasos   que   tenemos   que   hacer   siempre  antes  de  distribuir  públicamente  una  aplicación.      Adicionalmentes,  durante  el  desarrollo  de   la  misma,  para   realizar  pruebas  y   la  depuración  del  código,   aunque  no   seamos   conscientes  de  ello   también  estamos   firmado   la   aplicación   con  un  “certificado  de  pruebas”.  Podemos  saber  en  qué  carpeta  de  nuestro  sistema  está  almacenado  este  certificado  accediendo  desde  Eclipse  al  menú  Window/Preferences y accediendo a la sección Android/Build.  

Page 121: Manual Inicio Android (1).pdf

 

  120  

 

Imagen  40  

11. Como   se   puede   observar,   en   mi   caso   el   certificado   de   pruebas   está   en   la   ruta  “C:\Users\NELSONCROZBY\.android\debug.keystore”.   Pues   bien,   para   obtener  nuestra  huella  digital   SHA1  deberemos  acceder  a  dicha   ruta  desde   la   consola  de   comando  de  Windows  y  ejecutar  los  siguientes  comandos:  

C:\>cd C:\Users\NELSONCROZBY\.android\

C:\Users\NELSONCROZBY\.android>"C:\Program Files (x86) \Java \jdk1.7.0_07 \bin\keytool.exe" -list -v -keystore debug.keystore -alias androiddebugkey -storepass android -keypass android  

12. Suponiendo   que   tu   instalación   de   Java   está   en   la   ruta   “C:\Program Files\Java\jdk1.7.0_07“.   Si   no   es   así   sólo   debes   sustituir   ésta   por   la   correcta.   Esto   nos  deberá  devolver  varios  datos  del  certificado,  entre  ellos  la  huella  SHA1.  

Page 122: Manual Inicio Android (1).pdf

 

  121  

 

Imagen  41  

13. Pues  bien,  nos  copiamos  este  dato  y  lo  añadimos  a  la  ventana  de  obtención  de  la  API  Key  donde  nos   habíamos   quedado   antes,   y   a   continuación   separado   por   un   punto   y   coma   añadimos   el  paquete   java   que   vayamos   a   utilizar   en   nuestra   aplicación,   que   en   mi   caso   será  “com.demo.proyectodemo″₺.  

 

Imagen  42  

14. Pulsamos  el  botón  “Create”  y  ya  deberíamos  tener  nuestra  API  Key  generada,  podremos  verla  en   la   pantalla   siguiente   dentro   del   apartado   “Key   for   Android   Apps   (with   certificates)”.  Apuntaremos  también  este  dato  para  utilizarlo  más  tarde.  

Page 123: Manual Inicio Android (1).pdf

 

  122  

 

Imagen  43  

15. Con  esto  ya  habríamos  concluido  los  preparativos  iniciales  necesarios  para  utilizar  el  servicio  de  mapas  de  Android  en  nuestras  propias  aplicaciones,  por  lo  que  modificaremos  nuestro  proyecto  de  ejemplo  en  Eclipse.  

16. lo  primero  que  haremos  será  añadir  al  fichero  AndroidManifest.xml  la  API  Key  que  acabamos  de  generar.   Para   ello   añadiremos   al   fichero,   dentro   de   la   etiqueta  <application>,   un   nuevo  elemento  <meta-­‐data>  con  los  siguientes  datos:  

 

Imagen  44  

17. Como   valor   del   parámetro   android:value   tendremos   que   poner   nuestra   API   Key   recién  generada. En   mi   caso   mi   API   Key   generada   es:  AIzaSyDmw0rDncgMS1TbUkaXavswHdZRdMbyw6w (recuerda   este   valor   es   para   el   caso  mío,  aquí  debe  de  ir  valor  que  a  ustedes  les  genera).  

18. Siguiendo   con   el   AndroidManifest,   también   tendremos   que   incluir   una   serie   de   permisos   que  nos   permitan   hacer   uso   de   los   mapas.   En   primer   lugar   tendremos   que   definir   y   utilizar   un  permiso   llamado   “tu.paquete.java.permission.MAPS_RECEIVE”,   estas   etiquetas  deben   de   ser   colocadas   antes   de   la   etiqueta   <application,   en   mi   caso   quedaría   de   la  siguiente   forma   (recordemos   y   tengamos   mucho   cuidado   de   usar   el   nombre   del   paquete  principal  de  su  proyect:  

 

Imagen  45  

19. Además,   tendremos  que  añadir  permisos  adicionales  que  nos  permitan  acceder  a   los  servicios  web  de  Google,  a  Internet,  y  al  almacenamiento  externo  del  dispositivo  (utilizado  para  la  caché  de  los  mapas),  estos  permisos  son  colocados  inmediatamente  después  de  los  anteriores:  

Page 124: Manual Inicio Android (1).pdf

 

  123  

 

Imagen  46  

20. Por  último,  dado  que  la  API  v2  de  Google  Maps  Android  utiliza  OpenGL  ES  versión  2,  deberemos  especificar  también  dicho  requisito  en  nuestro  AndroidManifest  añadiendo  un  nuevo  elemento  <uses-feature> inmediatamente  después  de  los  permisos  anteriores:  

 

Imagen  47  

21. Una  vez  hemos  configurado  todo  lo  necesario  en  el  AndroidManifest,  y  antes  de  escribir  nuestro  código,   tenemos  que   seguir  añadiendo  elementos  externos  a  nuestro  proyecto.  El  primero  de  ellos  será  referenciar  desde  nuestro  proyecto  la  librería  con  el  SDK  de  Google  Play  Services  que  nos   descargamos   al   principio   de   este   tutorial.   Para   ello,   desde   Eclipse   podemos   importar   la  librería  a  nuestro  conjunto  de  proyectos  mediante  la  opción  de  menú  “File / Import… / Existing Android Code Into Workspace”.  Como  ya  dijimos  este  paquete  se  localiza  en   la   ruta   “<carpeta-sdk-android>/extras/google/google_play_services/libproject/google-

play-services_lib“.  

 

Imagen  48  

Page 125: Manual Inicio Android (1).pdf

 

  124  

22. Tras  seleccionar   la  ruta  correcta  dejaremos  el   resto  de  opciones  con  sus  valores  por  defecto  y  pulsaremos  Finish  para  que  Eclipse  importe  esta  librería  a  nuestro  conjunto  de  proyectos.  

23. El   siguiente   paso   será   referenciar   esta   librería   desde   nuestro   proyecto   de   ejemplo.   Para   ello  iremos   a   sus   propiedades   pulsando   botón   derecho   /   Properties   sobre   nuestro   proyecto   y  accediendo   a   la   sección   Android   de   las   preferencias.   En   dicha   ventana   podemos   añadir   una  nueva   librería   en   la   sección   inferior   llamada   Library.   Cuando   pulsamos   el   botón   “Add…”   nos  aparecerá   la   librería   recién   importada   y   podremos   seleccionarla   directamente,   añadiéndose   a  nuestra  lista  de  librerías  referenciadas  por  nuestro  proyecto.  

 

Imagen  49  

24. Como  último  paso  de  configuración  de  nuestro  proyecto,  si  queremos  que  nuestra  aplicación  se  pueda   ejecutar   desde   versiones   “antiguas”   de   Android   (concretamente   desde   la   versión   de  Android   2.2)   deberemos   asegurarnos   de   que   nuestro   proyecto   incluye   la   librería   android-­‐support-­‐v4.jar,   que  debería   aparecer   si   desplegamos   las   sección   “Android  Dependencies”   o   la  carpeta  “lib”  de  nuestro  proyecto.  

Page 126: Manual Inicio Android (1).pdf

 

  125  

 

Imagen  50  

25. Las   versiones  más   recientes   de  ADT   incluyen   por   defecto   esta   librería   en   nuestros   proyectos,  pero   si   no  está   incluida  podríamos  hacerlo  mediante   la   opción  del  menú   contextual   “Android  Tools  /  Add  Support  Library…”    sobre  el  proyecto,  o  bien  de  forma  manual.  

Pasos  para  construir  una  aplicación  básica  usando  la  API  de  Google  Maps  

Y   con   esto   hemos   terminado   de   configurar   todo   lo   necesario.   Ya   podemos   escribir   nuestro   código.   Y  para  este  primer  ejemplo  sobre  el  tema  nos  vamos  a  limitar  a  mostrar  un  mapa  en  la  pantalla  principal  de  la  aplicación.  Posteriormente  veremos  cómo  añadir  otras  opciones  o  elementos  al  mapa.  

1. Para  esto   tendremos   simplemente  que  añadir  el   control   correspondiente  al   layout  de  nuestra  actividad   en   este   caso   es  activity_mapa.xml.   En   el   caso   de   la   nueva   API   v2   este   “control”   se  añadirá   en   forma   de   fragment   (de   ahí   que   hayamos   tenido   que   incluir   la   librería   android-­‐support  para  poder  utilizarlos  en  versiones  de  Android  anteriores  a   la  3.0)  de  un  determinado  tipo   (concretamente   de   la   nueva   clase  com.google.android.gms.maps.SupportMapFragment),  quedando  por  ejemplo  de  la  siguiente  forma  (ver  Imagen  132):  

 

Imagen  51  

 

Gráficamente  el  diseño  de  la  interfaz  se  vería  como  se  muestra  en  la  Imagen  53.  

Page 127: Manual Inicio Android (1).pdf

 

  126  

 

Imagen  52  

2. Por  supuesto,  dado  que  estamos  utilizando  fragments,  la  actividad  MapasActivity.java  también  tendrá  que  extender  a  FragmentActivity  (en  vez  de  simplemente  Activity  como  es  lo  “normal”).  Usaremos  también   la  versión  de  FragmentActivity   incluida  en   la   librería  android-­‐support  para  ser  compatibles  con  la  mayoría  de  las  versiones  Android  actuales.  Veamos  la  Imagen  54  para  ver  cómo  queda  el  código  de  nuestra  activity.  

 

Imagen  53  

Con  esto,   ya   podríamos   ejecutar   y   probar   nuestra   aplicación.   En  mi   caso   las   pruebas   las   he   realizado  sobre  un  dispositivo  físico  con  Android  2.3.5  ya  que  por  el  momento  parece  haber  algunos  problemas  para  hacerlo  sobre  el  emulador.  Por  tanto  tendremos  que  conectar  nuestro  dispositivo    a  la  PC  mediante  el  cable  de  datos  e  indicar  a  Eclipse  que  lo  utilice  para  la  ejecución  de  la  aplicación.  

Page 128: Manual Inicio Android (1).pdf

 

  127  

En   la   Imagen   55   podemos   ver   una   captura   en   pantalla   de   la   ejecución   del   código   que   previamente  hemos  creado.  

 

Imagen  54  

  Interactuando  con  el  Mapa  (pasar  coordenadas)  

En  el  ejemplo  anterior   todo   lo  que  hicimos   fue   lo  necesario  para  configurar   la  API  de  Google  y  poder  cargar  un  mapa  en  nuestra  pantalla,  pero  ahora  lo  que  se  pretende  hacer  es  ya  interactuar  con  el  mapa,  en  qué  consistirá  esta  interacción,  pues  lo  primero  será  lograr  que  el  mapa  se  posicione  sobre  un  punto  en   específico   y   a   este   punto   le   colocaremos   unos   “markers”   personalizado   junto   a   algún   tipo   de  mensaje.    

1. Bueno   lo   primero   que   haremos   será   abrir   el   archivo  MapasActivity.java   para  modificarlo,   de  ahora  en  adelante  en  este  ejemplo  todo  lo  que  hagamos  será  en  esta  clase.  

2. Como   en   este   ejemplo   será   algo   demostrativa   y   simple   pondremos   las   coordenadas   de   dos  puntos  de   forma  manual   en  unas   variables   globales  del   tipo  LatLng,     en  posteriores   ejemplos  veremos  cómo  recuperar  la  posición  actual  a  través  del  GPS  del  celular  por  lo  pronto  veremos  la  Imagen  56  y  observamos  la  forma  de  declarar  las  coordenadas.  

 

Imagen  55  

Page 129: Manual Inicio Android (1).pdf

 

  128  

3. Ahora  pasaremos  a  inicializar  la  variable  del  tipo  GoogleMap  declarada  y  el  elemento  respectivo  del  layout.  En  la  siguiente  Imagen  podemos  ver  cómo  se  hace  (recuerda  que  esto  se  hace  en  el  método  onCreate):  

 

Imagen  56  

4. Posteriormente   agregaremos   los  markers   para   cada   uno   de   los   puntos   que   crearemos   en   el  mapa   y   también   pondremos   el   zoom   de   inicio   sobre   el   mapa   y   declararemos   un   efecto   al  momento  de  hacer  zoom  sobre  el  mapa,  ver  Imagen  58  para  el  código.  

 

Imagen  57  

 

Localización  geográfica  en  Android  La  localización  geográfica  en  Android  es  uno  de  esos  servicios  que,  a  pesar  de  requerir  poco  código  para  ponerlos  en  marcha,  no  son  para  nada  intuitivos  ni  fáciles  de  llegar  a  comprender  por  completo.  Y  esto  no   es   debido   al   diseño   de   la   plataforma   Android   en   sí,   sino   a   la   propia   naturaleza   de   este   tipo   de  servicios.   Por   un   lado,   existen  multitud   de   formas   de   obtener   la   localización   de   un   dispositivo  móvil,  aunque  la  más  conocida  y  popular  es  la  localización  por  GPS,  también  es  posible  obtener  la  posición  de  un  dispositivo  por  ejemplo  a  través  de  las  antenas  de  telefonía  móvil  o  mediante  puntos  de  acceso  Wi-­‐Fi  cercanos,  y  todos  cada  uno  de  estos  mecanismos  tiene  una  precisión,  velocidad  y  consumo  de  recursos  distinto.   Por   otro   lado,   el   modo   de   funcionamiento   de   cada   uno   de   estos   mecanismos   hace   que   su  utilización  desde  nuestro  código  no  sea  todo  lo  directa  e  intuitiva  que  se  desearía.  Iremos  comentando  todo  esto  a  lo  largo  del  documento,  pero  vayamos  paso  a  paso.  

¿Qué  mecanismos  de  localización  tenemos  disponibles?  

Lo   primero   que   debe   conocer   una   aplicación   que   necesite   obtener   la   localización   geográfica   es   qué  mecanismos  de   localización   (proveedores  de   localización,  o   location  providers)   tiene  disponibles  en  el  dispositivo.  Como  ya  hemos  comentado,  los  más  comunes  serán  el  GPS  y  la  localización  mediante  la  red  de  telefonía,  pero  podrían  existir  otros  según  el  tipo  de  dispositivo.  

Page 130: Manual Inicio Android (1).pdf

 

  129  

La  forma  más  sencilla  de  saber  los  proveedores  disponibles  en  el  dispositivo  es  mediante  una  llamada  al  método   getAllProviders()   de   la   clase   LocationManager,   clase   principal   en   la   que   nos  basaremos  siempre  a   la  hora  de  utilizar   la  API  de   localización  de  Android.  Para  ello,  obtendremos  una  referencia   al   location   manager   llamando   a   getSystemService(LOCATION_SERVICE),   y  posteriormente  obtendremos  la  lista  de  proveedores  mediante  el  método  citado  para  obtener  la  lista  de  nombres  de  los  proveedores:  

 

Imagen  58  

Una  vez  obtenida  la  lista  completa  de  proveedores  disponibles  podríamos  acceder  a  las  propiedades  de  cualquiera   de   ellos   (precisión,   coste,   consumo   de   recursos,   o   si   es   capaz   de   obtener   la   altitud,   la  velocidad,   etc).   Así,   podemos   obtener   una   referencia   al   provider   mediante   su   nombre   llamando   al  método  getProvider(nombre)  y  posteriormente  utilizar  los  métodos  disponibles  para  conocer  sus  propiedades,   por   ejemplo   getAccuracy()   para   saber   su   precisión   (tenemos   disponibles   las  constantes   Criteria.ACCURACY_FINE   para   precisión   alta,   y   Criteria.ACCURACY_COARSE  para   precisión   media),   supportsAltitude()   para   saber   si   obtiene   la   altitud,   o  getPowerRequirement()   para   obtener   el   nivel   de   consumo   de   recursos   del   proveedor.   La   lista  completa   de   métodos   para   obtener   las   características   de   un   proveedor   se   puede   consultar   en   la  documentación  oficial  de  la  clase  LocationProvider.  

 

Imagen  59  

Al   margen   de   esto,   hay   que   tener   en   cuenta   que   la   lista   de   proveedores   devuelta   por   el   método  getAllProviders()  contendrá  todos  los  proveedores  de  localización  conocidos  por  el  dispositivo,  incluso  si  éstos  no  están  permitidos   (según   los  permisos  de   la  aplicación)  o  no  están  activados,  por   lo  que  esta  información  puede  que  no  nos  sea  de  mucha  ayuda.  

¿Qué  proveedor  de  localización  es  mejor  para  mi  aplicación?  

Android   proporciona   un   mecanismo   alternativo   para   obtener   los   proveedores   que   cumplen   unos  determinados   requisitos   entre   todos   los   disponibles.   Para   ello   nos   permite   definir   un   criterio   de  búsqueda,   mediante   un   objeto   de   tipo   Criteria,   en   el   que   podremos   indicar   las   características  mínimas  del  proveedor  que  necesitamos  utilizar   (podéis  consultar   la  documentación  oficial  de   la  clase  Criteria  para  saber  todas  las  características  que  podemos  definir).  Así,  por  ejemplo,  para  buscar  uno  con  precisión  alta  y  que  nos  proporcione  la  altitud  definiríamos  el  siguiente  criterio  de  búsqueda:  

Page 131: Manual Inicio Android (1).pdf

 

  130  

 

Imagen  60  

Tras  esto,  podremos  utilizar  los  métodos  getProviders()  o  getBestProvider()  para  obtener  la   lista  de  proveedores  que  se  ajustan  mejor  al   criterio  definido  o  el  proveedor  que  mejor   se  ajusta  a  dicho  criterio,  respectivamente.  Además,  ambos  métodos  reciben  un  segundo  parámetro  que  indica  si  queremos   que   sólo   nos   devuelvan   proveedores   que   están   activados   actualmente.   Veamos   cómo   se  utilizarían  estos  métodos:  

 

Imagen  61  

Con  esto,  ya  tenemos  una  forma  de  seleccionar  en  cada  dispositivo  aquel  proveedor  que  mejor  se  ajusta  a  nuestras  necesidades.  

¿Está  disponible  y  activado  un  proveedor  determinado?  

Aunque,   como   ya   hemos   visto,   tenemos   la   posibilidad   de   buscar   dinámicamente   proveedores   de  localización  según  un  determinado  criterio  de  búsqueda,  es  bastante  común  que  nuestra  aplicación  esté  diseñada  para  utilizar  uno  en  concreto,  por  ejemplo  el  GPS,  y  por  tanto  necesitaremos  algún  mecanismo  para  saber  si  éste  está  activado  o  no  en  el  dispositivo.  Para  esta  tarea,  la  clase  LocationManager  nos  proporciona  otro  método   llamado  isProviderEnabled()   que  nos  permite  hacer  exactamente   lo  que  necesitamos.  Para  ello,  debemos  pasarle  el  nombre  del  provider  que  queremos  consultar.  Para  los  más  comunes  tenemos  varias  constantes  ya  definidas:  

• LocationManager.NETWORK_PROVIDER.  Localización  por  la  red  de  telefonía.  • LocationManager.GPS_PROVIDER.  Localización  por  GPS.  

De   esta   forma,   si   quisiéramos   saber   si   el   GPS   está   habilitado   o   no   en   el   dispositivo   (y   actuar   en  consecuencia),  haríamos  algo  parecido  a    lo  siguiente:  

 

Imagen  62  

Page 132: Manual Inicio Android (1).pdf

 

  131  

En  el   código  anterior,  verificamos  si  el  GPS  está  activado  y  en  caso  negativo  mostramos  al  usuario  un  mensaje  de  advertencia.  Este  mensaje  podríamos  mostrarlo  sencillamente  en  forma  de  notificación  de  tipo  toast,  

El  GPS  ya  está  activado,  ¿y  ahora  qué?  

Una   vez   que   sabemos   que   nuestro   proveedor   de   localización   favorito   está   activado,   ya   estamos   en  disposición  de   intentar   obtener   nuestra   localización   actual.   Y   aquí   es   donde   las   cosas   empiezan   a   ser  menos  intuitivas.  Para  empezar,  en  Android  no  existe  ningún  método  del  tipo  “obtenerPosiciónActual()“.  Obtener  la  posición  a  través  de  un  dispositivo  de  localización  como  por  ejemplo  el  GPS  no  es  una  tarea  inmediata,  sino  que  puede  requerir  de  un  cierto  tiempo  de  procesamiento  y  de  espera,  por   lo  que  no  tendría  sentido  proporcionar  un  método  de  ese  tipo.  

Si   buscamos   entre   los   métodos   disponibles   en   la   clase   LocationManager,   lo   más   parecido   que  encontramos  es  un  método   llamado  getLastKnownLocation(String provider),  que  como  se  puede  suponer  por  su  nombre,  nos  devuelve  la  última  posición  conocida  del  dispositivo  devuelta  por  un  provider   determinado.   Es   importante   entender   esto:   este  método  NO  devuelve   la   posición   actual,  este   método   NO   solicita   una   nueva   posición   al   proveedor   de   localización,   este   método   se   limita   a  devolver  la  última  posición  que  se  obtuvo  a  través  del  proveedor  que  se  le  indique  como  parámetro.  Y  esta   posición   se   pudo   obtener   hace   pocos   segundos,   hace   días,   hace   meses,   o   incluso   nunca   (si   el  dispositivo  ha  estado  apagado,  si  nunca  se  ha  activado  el  GPS,  etc.).  Por  tanto,  cuidado  cuando  se  haga  uso  de  la  posición  devuelta  por  el  método  getLastKnownLocation().  

Entonces,   ¿de   qué   forma   podemos   obtener   la   posición   real   actualizada?   Pues   la   forma   correcta   de  proceder   va   a   consistir   en   algo   así   como   activar   el   proveedor   de   localización   y   suscribirnos   a   sus  notificaciones   de   cambio   de   posición.   O   dicho   de   otra   forma,   vamos   a   suscribirnos   al   evento   que   se  lanza  cada  vez  que  un  proveedor  recibe  nuevos  datos  sobre  la  localización  actual.  Y  para  ello,  vamos  a  darle   previamente   unas   indicaciones   (que   no   son   ordenes)   sobre   cada   cuanto   tiempo   o   cada   cuanta  distancia  recorrida  necesitaríamos  tener  una  actualización  de  la  posición.  

Todo  esto   lo  vamos  a   realizar  mediante  una   llamada  al  método  requestLocationUpdates(),  al  que  deberemos  pasar  4  parámetros  distintos:  

• Nombre  del  proveedor  de  localización  al  que  nos  queremos  suscribir.  • Tiempo  mínimo  entre  actualizaciones,  en  milisegundos.  • Distancia  mínima  entre  actualizaciones,  en  metros.  • Instancia  de  un  objeto  LocationListener,   que   tendremos  que   implementar  previamente  

para  definir  las  acciones  a  realizar  al  recibir  cada  nueva  actualización  de  la  posición.  

Tanto  el  tiempo  como  la  distancia  entre  actualizaciones  pueden  pasarse  con  valor  0,  lo  que  indicaría  que  ese  criterio  no  se  tendrá  en  cuenta  a  la  hora  de  decidir  la  frecuencia  de  actualizaciones.  Si  ambos  valores  van   a   cero,   las   actualizaciones   de   posición   se   recibirán   tan   pronto   y   tan   frecuentemente   como   estén  disponibles.  Además,  como  ya  hemos  indicado,  es  importante  comprender  que  tanto  el  tiempo  como  la  

Page 133: Manual Inicio Android (1).pdf

 

  132  

distancia   especificadas   se   entenderán   como   simples   indicaciones   o   “pistas”   para   el   proveedor,   por   lo  que  puede  que  no  se  cumplan  de  forma  estricta.  

En   cuanto   al   listener,   éste   será   del   tipo   LocationListener   y   contendrá   una   serie   de   métodos  asociados  a  los  distintos  eventos  que  podemos  recibir  del  proveedor:  

• onLocationChanged(location).  Lanzado  cada  vez  que  se  recibe  una  actualización  de  la  posición.  

• onProviderDisabled(provider).  Lanzado  cuando  el  proveedor  se  deshabilita.  • onProviderEnabled(provider).  Lanzado  cuando  el  proveedor  se  habilita.  • onStatusChanged(provider, status, extras).   Lanzado   cada   vez   que   el  

proveedor   cambia   su   estado,   que   puede   variar   entre   OUT_OF_SERVICE,  TEMPORARILY_UNAVAILABLE, AVAILABLE.  

Por   nuestra   parte,   tendremos   que   implementar   cada   uno   de   estos   métodos   para   responder   a   los  eventos   del   proveedor,   sobre   todo   al  más   interesante,  onLocationChanged(),   que   se   ejecutará  cada   vez   que   se   recibe   una   nueva   localización   desde   el   proveedor.   Veamos   un   ejemplo   de   cómo  implementar  un  listener  de  este  tipo:  

 

Imagen  63  

Como   podemos   ver,   en   nuestro   caso   de   ejemplo   nos   limitamos   a   mostrar   al   usuario   la   información  recibida   en   el   evento,   bien   sea   un   simple   cambio   de   estado,   o   una   nueva   posición,   en   cuyo   caso  llamamos  al  método  auxiliar  mostrarPosicion().  

En  el  método  mostrarPosicion()  nos  vamos  a  limitar  a  mostrar  los  distintos  datos  de  la  posición  pasada  como   parámetro   en   los   controles   correspondientes   de   la   interfaz,   utilizando   para   ello   los   métodos  proporcionados   por   la   clase   Location.   En   nuestro   caso   utilizaremos   getLatitude(),  getAltitude()  y  getAccuracy()  para  obtener   la   latitud,   longitud  y  precisión  respectivamente.  

Page 134: Manual Inicio Android (1).pdf

 

  133  

Por   supuesto,   hay   otros   métodos   disponibles   en   esta   clase   para   obtener   la   altura,   orientación,  velocidad,   etc…  que   se  pueden   consultar   en   la  documentación  oficial   de   la   clase   Location.  Veamos  el  código:  

 

Imagen  64  

¿Por  qué  comprobamos   si   la   localización   recibida  es  null?  Como  ya  hemos  dicho  anteriormente,  no  tenemos  mucho  control  sobre  el  momento  ni  la  frecuencia  con  la  que  vamos  a  recibir  las  actualizaciones  de  posición  desde  un  proveedor,  por  lo  que  tampoco  estamos  seguros  de  tenerlas  disponibles  desde  un  primer  momento.  Por  este  motivo,  una  técnica  bastante  común  es  utilizar   la  posición  que  devuelve  el  método   getLastKnownLocation()   como   posición   “provisional”   de   partida   y   a   partir   de   ahí  esperar  a  recibir  la  primera  actualización  a  través  del  LocationListener.  Y  como  también  dijimos,  la   última   posición   conocida   podría   no   existir   en   el   dispositivo,   de   ahí   que   comprobemos   si   el   valor  recibido  es  null.  Para  entender  mejor  esto,  a  continuación  tenéis   la  estructura  completa  del  método  que  lanzamos  al  comenzar  la  recepción  de  actualizaciones  de  posición:  

Page 135: Manual Inicio Android (1).pdf

 

  134  

 

Imagen  65  

Como  se  puede  observar,  al  comenzar  la  recepción  de  posiciones,  mostramos  en  primer  lugar  la  última  posición  conocida,  y  posteriormente  solicitamos  al  GPS  actualizaciones  de  posición  cada  30  segundos.  

En   las   Imágenes   67   -­‐   69   podemos   ver   la   el   diseño   gráfico   y   el   archivo   xml   que   utilizaremos   para   la  pantalla  de  la  interfaz  gráfica.  

Page 136: Manual Inicio Android (1).pdf

 

  135  

 

Imagen  66  

 

 

Imagen  67  

Page 137: Manual Inicio Android (1).pdf

 

  136  

 

Imagen  68  

En   las   siguientes   Imágenes   70   -­‐   74   podemos   ver   el   código   de   los   diferentes  métodos   que   conforman  nuestra  activity  TrazarActivity.java.  

 

Imagen  69.  Declaración  de  variables  globales.  

Page 138: Manual Inicio Android (1).pdf

 

  137  

 

Imagen  70.  Método  onCreate()  

 

Imagen  71.  Métodos  trazarRuta()  y  mostrarDestino()  

Page 139: Manual Inicio Android (1).pdf

 

  138  

 

Imagen  72.  Método  comenzarLocalizacion()  

 

Imagen  73.  Métodos  mostrarAvisoGpsDeshabilitado()  y  mostrarPosicion()  

Page 140: Manual Inicio Android (1).pdf

 

  139  

AsyncTask  La  clase  AsyncTask  nos  ayuda  a  los  desarrolladores  a  darle  un  uso  adecuado  y  más  fácil  al  UI  thread  de  nuestras  aplicaciones.  Permite  ejecutar  operaciones  en  segundo  plano  y  definir   los  resultados  en  el  UI  thread  sin    tener  que  quebrarnos  la  cabeza  manipulando  threads  y  handlers.  

Para  utilizar  AsyncTask  debemos:  

• Crear   una   subclase   de  AsyncTask,   comúnmente   como   una   clase   interna   privada   dentro   de   la  actividad  en  la  que  estemos  trabajando.  

• Sobreescribir  uno  o  más  métodos  de  AsyncTask  para  poder  realizar  el  trabajo  en  segundo  plano,  además   de   cualquier   otra   tarea   asociada   para   poder   mostrar   alguna   actualización   en   el   UI  thread.  

• Cuando  sea  necesario,  crear  una  instancia  de  AsyncTask  y  llamar  al  método  execute()  para  que  empiece  a  realizar  su  trabajo.  

Tipos  genéricos  

AsyncTask  utiliza  tipos  genéricos,  por   lo  que  resulta  necesario  definir  tres  tipos  de  datos  cada  vez  que  necesitemos  crear  una  instancia  de  esta  clase:  

• Parámetros  (Params).  El  tipo  de  información  que  se  necesita  para  procesar  la  tarea.  •  Progreso   (Progress).  El   tipo   de   información   que   se   pasa   dentro   de   la   tarea   para   indicar   su  

progreso.  •  Resultado  (Result).  El  tipo  de  información  que  se  pasa  cuando  la  tarea  ha  sido  completada.  

Hay   que   tener   en   cuenta   que   existen   casos   en   los   que   algún   tipo   genérico   no   es   utilizado   por   la  AsyncTask,  para  ello  utilizamos  el  tipo  Void  como  se  muestra  a  continuación:  

 

Etapas  del  ASyncTask  

Cada  vez  que  una  tarea  asíncrona  se  ejecuta,  se  pasa  a  través  de  4  etapas:  

1. onPreExceute().   Se   invoca   en   el   UI   thread   inmediatamente   después   de   que   la   tarea   es  ejecutada.   Este   paso   se   utiliza   normalmente   para   configurar   la   tarea.   El   ejemplo   básico   es  cuando  se  muestra  una  ProgressBar  en  la  interfaz  de  usuario.  

2. doInBackground(Params…).   Se   invoca   en   el   subproceso   en   segundo   plano   inmediatamente  después   de   que   onPreExecute()   termina   de   ejecutarse.   En   esta   etapa   se   calcula   el   tiempo  estimado  que  tomará  la  realización  de  la  tarea,  que  deberá  pasarse  a  la  última  etapa  de  todo  el  proceso.  Los  parámetros  de  la  tarea  asíncrona  también  se  pasan  en  esta  etapa.  Dentro  de  esta  etapa  podemos  utilizar  el  método  publishProgress(Progress…)  para  publicar  una  o  más  unidades  

Page 141: Manual Inicio Android (1).pdf

 

  140  

de   progreso   en   el  UI   thread   por   la   ayuda   de   la   siguiente   etapa   que   es  onProgressUpdate(Progress…).  

3. onProgressUpdate(Progress…).   Se   invoca   en   el   UI   thread   después   de   una   llamada   a  publishProgress(Progress…).  El  momento  de  la  ejecución  es  indefinido.  Este  método  es  utilizado  para  mostrar  cualquier  tipo  de  progreso  en  la  interfaz  de  usuario  mientras  la  tarea  en  segundo  plano  sigue  ejecutándose.  

4. onPostExecute(Result…).  Se  invoca  en  el  UI  thread  después  de  que  el  proceso  en  segundo  plano  ha   sido   terminado.   El   resultado   devuelto   por   todo   el   proceso   se   pasa   a   este   método   como  parámetro.  

Las  reglas  del  juego  

Para  poder  trabajar  sin  problemas  con  la  clase  AsyncTask,  existen  algunas  reglas  acerca  de  los  threads  que  debes  tomar  en  cuenta:  

• La  instancia  de  la  tarea  debe  crearse  en  el  UI  thread.  •  El  método  execute(Params…)  debe  invocarse  en  el  UI  thread.  •  Los  métodos  onPreExecute(),  onPostExecute(Result),  doInBackground(Params…),  on  

ProgressUpdate(Progress…)  no  deben  llamarse  de  forma  manual.  •  La  tarea  debe  ser  ejecutada  sólo  una  vez  (con  excepción  de  que  la  ejecución  corresponda  a  un  

segundo  intento).  

Navegación  Navegación  con  Back  y  Up  

La  navegación  consistente  es  un  componente  esencial  de  la  experiencia  general  del  usuario.  Hay  pocas  cosas  que  frustran  más  a  los  usuarios  de  navegación  básica  que  se  comporta  de  maneras  contradictorias  e  inesperadas.  Android  3.0  introdujo  cambios  significativos  en  el  comportamiento  global  de  navegación.  Cuidadosamente  siguiendo  las  directrices  para  atrás  (back)  y  hacia  arriba  (up)  hará  que  la  navegación  de  sus  aplicaciones  sea  previsible  y  fiable  para  los  usuarios.  

Android  2.3  y  anteriores  se  basó  en  el  sistema  de  botón  Atrás  para  apoyar  la  navegación  dentro  de  una  aplicación.   Con   la   introducción   de   las   barras   de   acción   en   Android   3.0,   un   segundo   mecanismo   de  navegación   apareció:   el   botón   de   arriba,   que   consiste   en   el   icono   de   la   aplicación   y   un   símbolo   de  intercalación  de  punto  a  la  izquierda.  

 

Page 142: Manual Inicio Android (1).pdf

 

  141  

Up  vs.  Back  

El   botón   Arriba   se   utiliza   para   navegar   dentro   de   una   aplicación   basada   en   las   relaciones   jerárquicas  entre   pantallas.   Por   ejemplo,   si   la   pantalla   A   muestra   una   lista   de   elementos,   y   la   selección   de   un  elemento   conduce   a   la   pantalla   de   B   (que   presenta   ese   tema   con   más   detalle),   a   continuación,   la  pantalla  B  debe  ofrecer  un  botón  Arriba  que  devuelve  a  la  pantalla  A.  

Si  una  pantalla  es  la  más  alta  en  una  aplicación  (es  decir,  el  hogar  de  la  aplicación),  no  debe  presentar  un  botón  Arriba.  

El  sistema  de  botón  Atrás  se  utiliza  para  navegar,  en  orden  cronológico  inverso,  a  través  de  la  historia  de  las   pantallas   que   el   usuario   ha   trabajado   recientemente.   Se   basa   generalmente   en   las   relaciones  temporales  entre  las  pantallas,  en  lugar  de  la  jerarquía  de  la  aplicación.  

Cuando  la  pantalla  vista  anteriormente  es  también  el  padre  jerarquico  de  la  pantalla  actual,  al  pulsar  el  botón   Atrás   tiene   el   mismo   resultado   que   al   pulsar   un   botón   Up   –esto   ocurre   comunmente.   Sin  embargo,  al  contrario  el  botón  de  arriba,   lo  que  garantiza  es  que  el  usuario  permanezca  dentro  de  su  aplicación,  el  botón  Atrás  puede  devolver  al  usuario  a   la  pantalla  de   inicio,  o   incluso  a  una  aplicación  diferente.  

 

El   botón   Back   también   es   compatible   con   algunos   comportamientos   que   no   están   directamente  vinculados  a  la  navegación  de  pantalla  a  la  pantalla:  

• Desestima  las  ventanas  flotantes  (diálogos,  popups)  • Desestimar  barras  de  acción  contextual,  y  elimina  el  resaltado  de  los  elementos  seleccionados  • Oculta  el  teclado  en  pantalla  (IME)  

 

Page 143: Manual Inicio Android (1).pdf

 

  142  

Navegación  dentro  de  su  aplicación  

1. Navegar  a  pantallas  con  múltiples  puntos  de  entrada  

A  veces,  una  pantalla  no  tiene  una  posición  estricta  dentro  de  la  jerarquía  de  la  aplicación,  y  se  puede  llegar  desde  múltiples  puntos  de  entrada-­‐tales  como  una  pantalla  de  configuración  que  se  puede  llegar  desde  cualquier  otra  pantalla  en  su  aplicación.  En  este  caso,  el  botón  UP  debería  optar  por  regresar  a  la  pantalla  de  referencia,  comportándose  de  forma  idéntica  al  fondo.  

2. Cambio  de  vista  en  una  pantalla  

Cambiar  las  opciones  de  visualización  para  la  pantalla  no  cambia  el  comportamiento  de  Up  o  posterior:  la  pantalla  sigue  en  el  mismo  lugar  dentro  de  la  jerarquía  de  la  aplicación,  y  no  se  crea  un  nuevo  historial  de  navegación.  

Ejemplos  de  tales  cambios  de  vista  son:  

• Vistas  de  conmutación  utilizando  pestañas  y  /  o  swipes  de  izquierda  y  derecha  • Cambiar  vistas  usando  un  menú  desplegable  (también  conocido  como  pestañas  colapsadas)  • Filtrando  un  a  lista  • Ordenando  una  lista  • Cambio  de  características  de  visualización  (como  el  zoom)  

 

3. Navegar  entre  pantallas  hermanas  

Cuando   la   aplicación   soporta   la  navegación  entre  una   lista  de  elementos  hacia  una   vista  detallada  de  uno  de  esos  artículos,  a  menudo  es  conveniente  que  soporte  la  dirección  de  navegación  a  partir  de  ese  punto   a   otro   que   le   precede   o   le   sigue   en   la   lista.   Por   ejemplo,   en   Gmail,   es   fácil   deslizar   hacia   la  izquierda  o  hacia  la  derecha  a  partir  de  una  conversación  para  ver  una  más  nueva  o  más  antigua  en  la  misma   bandeja   de   entrada.   Del   mismo   modo   que   al   cambiar   la   vista   en   una   pantalla,   como   la  navegación  no  cambia  el  comportamiento  de  Up  o  Back.  

Page 144: Manual Inicio Android (1).pdf

 

  143  

 

Sin   embargo,   una   notable   excepción   a   esto   ocurre   cuando   se   navega   entre   las   vistas   de   detalle  relacionados   no   ligadas   a   a   referida   lista   -­‐por   el   ejemplo,   cuando   se   navega   en   la   Play   Store   entre  aplicaciones   del  mismo   desarrollador,   o   álbumes   del  mismo   artista.   En   estos   casos,   después   de   cada  enlace   crea   la   historia,   haciendo   que   el   botón   Back   se   desplase   por   cada   pantalla   que   visualizada  anteriormente.   Up   podría   continuar   para   eludir   esas   pantallas   relacionadas   y   vaya   a   la   pantalla   de  contenedores  utilizada  más  recientemente.  

Page 145: Manual Inicio Android (1).pdf

 

  144  

 

También   se   tiene   la   capacidad   de   hacer   el   comportamiento   Up   aún   más   inteligente   basado   en   el  conocimiento   de   la   vista   de   detalle.   Ampliando   el   ejemplo   de   arriba   de   Play   Store,   imagine   que   el  usuario  ha  navegado  desde  el  último  libro  a  los  detalles  de  la  adaptación  de  la  película.  En  ese  caso,  Up  puede  volver  a  un  contenedor  (Películas),  que  el  usuario  no  ha  navegado  través  de  el.  

Page 146: Manual Inicio Android (1).pdf

 

  145  

 

 

Navegando   dentro   de   la   aplicación   vía   Widgets   en   la   pantalla   Home   y   las  Notificaciones.  

Puede  utilizar  los  widgets  de  la  pantalla  principal  o  notificaciones  para  ayudar  a  los  usuarios  a  navegar  directamente  a  las  pantallas  mas  profunds  de  la  jerarquía  de  su  aplicación.  Por  ejemplo,   la  Bandeja  de  entrada  del  widget  de  Gmail   y   la  notificación  de  nuevo  mensaje  pueden   saltar   la  pantalla  Bandeja  de  entrada,  llevando  al  usuario  directamente  a  una  vista  de  conversación.  

Para  ambos  de  estos  casos,  manejar  el  botón  UP  de  la  siguiente  manera:  

• Si   la   pantalla   de   destino   suele   ser   accesible   desde   una   pantalla   en   particular   dentro   de   la  aplicación,  Up  debería  navegar  a  esa  pantalla.  

• De  lo  contrario,  Up  debería  ir  a  la  pantalla  superior  ("Home")  de  su  aplicación.  

En  el  caso  del  botón  Back,  se  debe  hacer  la  navegación  más  predecible  mediante  la  inserción  en  la  pila  de  retroceso  de   la  ruta  completa  de  navegación  hacia  arriba  para   la  pantalla  superior  de   la  aplicación.  Esto   permite   a   los   usuarios   que   han   olvidado   como   ellos   entraron   en   la   aplicación   para   navegar   a   la  pantalla  superior  de  la  aplicación  antes  de  salir.  

Page 147: Manual Inicio Android (1).pdf

 

  146  

A  modo  de  ejemplo,  el  widget  de  Gmail  en  la  pantalla  Inicio  tiene  un  botón  para  el  salto  directamente  a  la  ventana  de  redacción.  O  la  vuelta  de  la  ventana  de  redacción  podría  llevar  al  usuario  a  la  Bandeja  de  entrada,  y  desde  allí  en  el  botón  Back  sigue  Home.  

 

Notificaciones  Indirectas  

Cuando   una   aplicación   necesita   para   presentar   información   sobre   varios   eventos   a   la   vez,   se   puede  utilizar  una  sola  notificación  que  dirige  al  usuario  a  una  pantalla  intersticial.  Esta  pantalla  resume  estos  eventos,   y   ofrece   caminos   para   que   el   usuario   sumergirse   profundamente   en   la   aplicación.  Notificaciones  de  este  estilo  se  denominan  notificaciones  indirectas.  

A   diferencia   de   las   notificaciones   estándar   (directas),   al   pulsar   Back   de   la   pantalla   intersticial   de   una  notificación  indirecta  devuelve  al  usuario  al  punto  donde  la  notificación  se  desencadenó  -­‐no  se  insertan  pantallas  adicionales  en   la  pila  de  retroceso.  Una  vez  que  el  usuario  procede  en   la  aplicación  desde   la  pantalla  intersticial,  Up  y  Back  se  comportan  como  para  las  notificaciones  estándar,  tal  como  se  describe  más  arriba:  navegando  dentro  de  la  aplicación  en  lugar  de  volver  al  intersticial.  

Por  ejemplo,  supongamos  que  un  usuario  de  Gmail  recibe  una  notificación  indirecta  desde  Calendario.  Al   tocar   esta   notificación   se   abre   la   pantalla   intersticial,   que   muestra   recordatorios   para   diferentes  eventos.   Tocando   Back   desde   la   intersticial   devuelve   al   usuario   a   Gmail.   Al   tocar   en   un   evento   en  particular   lleva   al   usuario   lejos   de   la   intersticial   e   ingresando  por   completo   a   la   aplicación  Calendario  para  mostrar  los  detalles  del  evento.  A  partir  de  los  detalles  del  evento,  arriba  y  atrás  navegar  a  la  vista  de  nivel  superior  de  Calendario.  

Page 148: Manual Inicio Android (1).pdf

 

  147  

 

Notificaciones  pop-­‐up  

Las  notificaciones  pop-­‐up  evitan  el  buzón  de  notificaciones,  en  lugar  de  eso  aparecen  directamente  en  frente   del   usuario.   Rara   vez   se   utilizan,   y   deben   reservarse   para   ocasiones   en   que   se   requiere   una  respuesta  oportuna  y   la   interrupción  del  contexto  del  usuario  si  es  necesario.  Por  ejemplo,  Talk  utiliza  este  estilo  para  alertar  al  usuario  de  la  invitación  de  un  amigo  a  unirse  a  un  chat  de  vídeo,  ya  que  esta  invitación  caducará  automáticamente  después  de  unos  segundos.  

En   términos   de   comportamiento   de   navegación,   las   notificaciones   emergentes   siguen   de   cerca   el  comportamiento   de   la   pantalla   intersticial   de   una   notificación   indirecta.   Back   descarta   la   notificación  emergente.   Si   el   usuario   se   desplaza   desde   el   pop-­‐up   en   la   aplicación   notifica,   Up   y   Back   siguen   las  reglas  para  las  notificaciones  estándar,  navegando  dentro  de  la  aplicación.  

Page 149: Manual Inicio Android (1).pdf

 

  148  

 

Navegando  entre  aplicaciones  

Una   de   las   fortalezas   fundamentales   del   sistema   Android   es   la   capacidad   de   las   aplicaciones   para  activarse  entre  sí,  dando  al  usuario  la  posibilidad  de  navegar  directamente  desde  una  aplicación  a  otra.  Por  ejemplo,  una  aplicación  que  necesita  capturar  una  foto  puede  activar  la  aplicación  de  la  cámara,  que  devolverá   la   foto   a   la   aplicación.   Este   es   un   gran   beneficio   tanto   para   el   desarrollador,   que   puede  aprovechar   fácilmente   el   código   de   otras   aplicaciones,   y   el   usuario   que   disfruta   de   una   experiencia  consistente  para  las  acciones  que  se  realizan  normalmente.  

Para   entender   la   navegación   aplicación  a   aplicación,   es   importante   para   entender   el   marco   de  comportamiento  de  Android  que  se  discute  a  continuación.  

• Actividades,  tareas  e    intents  

En  Android,   una   actividad   es   un   componente  de   aplicación  que  define   una  pantalla   de   información   y  todas   las   acciones   asociadas   que   el   usuario   puede   realizar.   Las   aplicaciones   son   una   colección   de  actividades,  que  constan  tanto  de  las  actividades  que  se  crean  y  las  que  se  reusan  de  otras  aplicaciones.  

Page 150: Manual Inicio Android (1).pdf

 

  149  

Una  tarea  es  la  secuencia  de  actividades  de  un  usuario  sigue  para  lograr  una  meta.  Una  sola  tarea  puede  hacer  uso  de  las  actividades  de  una  sola  aplicación,  o  puede  basarse  en  las  actividades  de  un  número  de  diferentes  aplicaciones.  

Un  intent  es  un  mecanismo  para  que  una  aplicación  indique  que  le  gustaría  la  ayuda  de  otra  aplicación  en  la  realización  de  una  acción.  Las  actividades  de  una  aplicación  pueden  indicar  a  cuales  intents  pueda  responder.   Para   los   intents   comunes   tales   como   "Compartir",   el   usuario   puede   tener   muchas  aplicaciones  instaladas  que  pueden  cumplir  esa  petición.  

• Ejemplo:  navegación  entre  aplicaciones  para  apoyar  el  intercambio  

Para   comprender   cómo   las   actividades,   tareas,   y   los   intents   trabajan   juntos,   considere   cómo   una  aplicación   permite   a   los   usuarios   compartir   contenido   utilizando   otra   aplicación.   Por   ejemplo,   el  lanzamiento   de   la   aplicación   Play   Store   desde   Home   comienza   nueva   tarea   A   (ver   figura   siguiente).  Después  de  navegar  a  través  de  la  Play  Store  y  tocar  un  libro  promovido  para  ver  sus  detalles,  el  usuario  permanece  en  la  misma  tarea,  que  se  extiende  mediante  la  adición  de  actividades.  Activando  la  acción  Compartir  pide  al  usuario  con  un  diálogo  donde  se  enumeran  cada  una  de  las  actividades  (de  diferentes  aplicaciones)  que  se  han  registrado  para  manejar  el  intent  Compartir.  

 

Page 151: Manual Inicio Android (1).pdf

 

  150  

Cuando  el  usuario  decide  compartir  a  través  de  Gmail,  se  añade  la  actividad  de  redacción  de  Gmail  como  una   continuación   de   la   tarea   A-­‐ninguna   nueva   tarea   se   crea.   Si   Gmail   tenía   su   propia   tarea   en  funcionamiento  en  segundo  plano,  no  se  vería  afectada.  

Desde   la  actividad  de  redacción,  enviando  el  mensaje  o  tocando  el  botón  Back,  regresa  al  usuario  a   la  actividad   de   detalles   del   libro.   Toques   posteriores   de   Back   continuan   navegando   a   través   de   la   Play  Store,    llegando  hasta  Home.  

 

Sin  embargo,  al  tocar  Up  en  la  actividad  de  redacción,  el  usuario  indica  un  deseo  de  permanecer  dentro  de  Gmail.  Aparece  la  actividad  lista  de  conversaciones  de  Gmail,  y  una  nueva  Tarea  B  se  crea  para  ello.  Nuevas   tareas   siempre   están   arraigadas   a   la   portada,   por   lo   que   tocando   Back   desde   la   lista   de  conversación  se  vuelve  allí.  

Page 152: Manual Inicio Android (1).pdf

 

  151  

 

La  tarea  A  persiste  en  el  fondo,  y  el  usuario  puede  volver  a  ella  más  tarde  (por  ejemplo,  a  través  de  la  pantalla  Recientes).  Si  Gmail  ya  tenía  su  propio  tarea  funcionando  en  segundo  plano,  sería  sustituida  por  la  tarea  B  -­‐el  contexto  previo  se  abandona  en  favor  de  la  nueva  meta  del  usuario.  

Cuando  la  aplicación  registra  manejar  los  intentos  con  una  actividad  profunda  dentro  de  la  jerarquía  de  la   aplicación,   consulte   Navegación   en   su   aplicación   a   través   de   widgets   de   la   pantalla   principal   y  Notificaciones  para  obtener  orientación  sobre  cómo  especificar  de  navegación  hacia  arriba.  

 

         

Page 153: Manual Inicio Android (1).pdf

 

  152  

Estilos  en  Android    

Dispositivos  y  Pantallas    

Android   potencializa   a  millones   de   teléfonos,   tabletas   y   otros   dispositivos   en   una   amplia   variedad  de  tamaños  de  pantalla  y   factores  de   forma.  Al   tomar  ventaja  del   sistema  de  diseño   flexible  de  Android,  se    pueden   crear   aplicaciones   que   se   adapten   a   la     escala   de   grandes   tabletas   así   como   también  de    teléfonos  más  pequeños.  

   

Sea  flexible    

Estirar  y  comprimir  sus  diseños  para  adaptarse  a  diferentes  alturas  y  anchuras.  

Optimice  los  diseños    

En   los   dispositivos   más   grandes,   se   debe    aprovechar   el   espacio   adicional   en   pantalla.   Cree   vistas  compuestas  que  combinan  múltiples  vistas  para  revelar  más  contenido  y    facilidad  de  navegación.  

 

Page 154: Manual Inicio Android (1).pdf

 

  153  

Activos  para  todos  

Proporcionar  recursos  para  diferentes  densidades  de  pantalla  (DPI)  para  garantizar  que  su  aplicación  se  vea  bien  en  cualquier  dispositivo.  

 

 

 

 

 

 

Estrategias    

Así   que,   ¿por   dónde   empezar   cuando   se   diseña   para   múltiples   pantallas?   Un   método   consiste   en  trabajar  en   la  norma  base   (tamaño  normal  y  MDPI)  y  escalar  hacia  arriba  o  hacia  abajo  para   los  otros  cubos.  Otro  método  consiste  en  comenzar  con  el  dispositivo  con  el   tamaño  de  pantalla  más  grande,  y  después   escalar   hacia   abajo   y   averiguar   el   tipo     interfaz   de   usuario   que   se   necesitara   hacer   para  ajustarlo  en  las  pantallas  más  pequeñas.  

 

Temas  

Los   temas   son   el   mecanismo   de   Android   para   aplicar   un   estilo   coherente   con   una   aplicación   o  actividad.  El   estilo   especifica   las   propiedades   visuales   de   los   elementos   que   componen   la   interfaz   de  usuario,  como  el  color,  la  altura,  el  relleno  y  el  tamaño  de  la  fuente.  Para  promover  una  mayor  cohesión  entre   todas   las   aplicaciones   en   la   plataforma,   Android   proporciona   dos   temas   del   sistema   que   usted  puede  elegir  la  hora  de  la  creación  de  aplicaciones:  

• Holo  Light  • Holo  Black  

La   aplicación   de   estos   temas   recorren   un   largo   camino   para   ayudar   a   construir   aplicaciones   que   se  adapten  correctamente  en  el  lenguaje  visual  general  de  Android.  

 

 

 

 

Page 155: Manual Inicio Android (1).pdf

 

  154  

 

 

 

 

 

Gmail  en  Holo  Light.  

 

 

 

 

 

 

 

 

 

Ajustes  en  Holo  Black.  

 

 

Elija  el   tema  del   sistema  que  mejor  se  adapte  a   las  necesidades  y   la  estética  de  diseño  para  su  aplicación.  Si  su  deseo  es  tener  una  mirada  más  clara  para  su  aplicación,  utilizando  uno  de  los  temas  del  sistema  como   punto   de   partida   para   las   personalizaciones   es   una   buena  idea.  Los   temas   del   sistema   proporcionan   una   base   sólida   sobre   la  que  se  puede   implementar  de  forma  selectiva  sus  propios  estilismos  visuales.  

 

 

 

Page 156: Manual Inicio Android (1).pdf

 

  155  

Retroalimentación  al  Toque  

Utilizar   iluminación   y   oscurecimiento   al   responder   a   los   toques,   reforzar   los   comportamientos  resultantes  de  gestos,  e  indicar  qué  acciones  están  activadas  y  desactivadas.  

Sea  sensible  a   toques  de  una  manera  suave.  Cada  vez  que  un  usuario   toca  un  área  procesable  en  su  aplicación,   hacerles   saber   que   la   aplicación   está   "escuchando",   proporcionando   una   respuesta   visual.  Que  sea  sutil  sólo  un  poco  más  claro  o  más  oscuro  que  el  color  intacto.  Esto  proporciona  dos  beneficios:  

• Chispazos  son  más  agradable  que  las  sacudidas.  • La   incorporación   de   su   marcan   es   mucho   más   fácil   porque   la   retroalimentación   táctil   de  

regeneración  funciona  con  cualquier  color  que  elija.  

 

 

 

Page 157: Manual Inicio Android (1).pdf

 

  156  

Estados  

 

La   mayor   parte   de   los   elementos   de   interfaz   de   usuario   de   Android   tienen   retroalimentación   táctil  incorporada,  incluyendo  estados  que  indican  si  tocar  el  elemento  tendrá  ningún  efecto.  

Comunicación  

Cuando  los  objetos  reaccionan  a  los  gestos  más  complejos,  ayudan  a  los  usuarios  a  entender  cuál  será  el  resultado.  

 

Page 158: Manual Inicio Android (1).pdf

 

  157  

En  “Recientes”,  cuando  un  usuario  inicia  a  deslizar  la  miniatura  hacia  la  izquierda  o  la  derecha,  comienza  a   oscurecerse.   Esto   ayuda   al   usuario   a   comprender   que   el   deslizamiento   hará   que   el   elemento   será  removido  

Límites  Cuando  los  usuarios  intentan  desplazarse  más  allá  del  principio  o  al  final  de  un  área  de  desplazamiento,  se   comunica   el   límite   con  una   señal   visual.  Muchos  de   los  widgets   de   interfaz   de  usuario   de  Android  desplazables,  como  listas  y  listas  de  la  red,  tienen  retroalimentación  de  apoyo  para  el  límite  integrado.  Si  usted   está   construyendo   widgets   personalizados,   tenga   retroalimentación   del   límite   en   mente   y  ofrezcala  en  su  aplicación.  

 

 

Métricas  y  Rejillas  

Los  dispositivos  varían  no  sólo  en  tamaño  físico,  sino  también  en  la  densidad  de  la  pantalla  (DPI).  Para  simplificar   la   forma   de   diseñar   para  múltiples   pantallas,   pensar   en   cada   dispositivo   como   caer   en   un  cubo  de  tamaño  y  densidad  cubo  especial:  

• Los  cubos  de  tamaño  son  el  hanset  (menor  que  600  DP)  y  la  tableta  (mayor  que  o  igual  600dp).  

Si  un  usuario   intenta  desplazarse  más  allá  del  último  panel  de   la  pantalla   de   inicio,   el   contenido  de   la   pantalla   se   inclina   hacia   la  derecha  para   indicar  que  una  mayor  navegación  en   este   sentido  no  es  posible.  

Page 159: Manual Inicio Android (1).pdf

 

  158  

• Los  cubos  de  densidad  son  LDPI,  MDPI,  IPAP,  XHDPI,  XXHDPI,  y  XXXHDPI.  

Optimizar   la   interfaz   de   usuario   de   la   aplicación   mediante   el   diseño   de   esquemas   alternativos   para  algunos  de  los  diferentes  grupos  de  tamaño,  y  proporcionar  imágenes  de  mapa  de  bits  alternativos  para  diferentes  cubos  de  densidad.  

Porque  es   importante  que  al  diseñar  e   implementar  sus  diseños  para  varias  densidades,   las  siguientes  instrucciones  se  refieren  a  las  dimensiones  de  diseño  con  mediciones  dp  en    lugar  de  píxeles.  

 

 

48dp  Rhythm  

Los  Componentes  en  la  interfazque  el  usuario  puede  tocar  o  manejar  son  generalmente  dispuestas  a  lo  largo  de  48dp  unidades.  

 

¿Por    qué  48dp?  En   promedio,   48dp   se   traducen   a   un   tamaño   físico   de   aproximadamente   de   9   mm   (con   cierta  variabilidad).  Esto  es  cómodo  en  la  gama  de  tamaños  recomendados  (7-­‐10  mm)  para   los  objetos  de   la  pantalla  táctil  y  los  usuarios  serán  capaces  de  forma  fiable  y  precisa  apuntarlos  con  sus  dedos.  

Si  el  diseño  de  los  elementos  son  de    al  menos  48dp  alto  y  ancho  usted  puede  garantizar  que:  

• sus   objetivos   nunca   será   menor   que   el   tamaño   mínimo   recomendado   de   7mm,  independientemente  de  lo  que  se  muestre  en  la  pantalla.  

Consideraciones  sobre  el  espacio  Dispositivos  varían  en  la  cantidad  de  píxeles  independientes  de  la  densidad  (dp)  que  se    pueden  mostrar.  

Page 160: Manual Inicio Android (1).pdf

 

  159  

• usted  tiene  un  buena  realción  entre  la  densidad  de  información  general  por  un  lado,  y  la    selección    de  elementos  de  la  interfaz  en  el  otro.

 

Cuidado  con  el  hueco  El  espacio  entre  cada  elemento  de  la  interfaz  de  usuario  es  8dp.  

Ejemplos:  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Page 161: Manual Inicio Android (1).pdf

 

  160  

Tipografía  

El   lenguaje  de  diseño  de  Android  se  basa  en  herramientas  tipográficas  tradicionales  como  la  escala,  el  espacio,   el   ritmo   y   la   alineación   con   una   cuadrícula   subyacente.   La   implementación   exitosa   de   estas  herramientas   es   esencial   para   ayudar   a   los   usuarios   a   comprender   rápidamente   una   pantalla   de  información.  Para  apoyar  este  uso  de   la   tipografía,  desde   la  versión   Ice  Cream  Sandwich   se   introduce  una   nueva   familia   tipográfica   con   nombre   Roboto,   creada   específicamente   para   los   requisitos   de   la  interfaz  de  usuario  y  las  pantallas  de  alta  resolución.

 

 

Page 162: Manual Inicio Android (1).pdf

 

  161  

El  actual  marco  TextView  ofrece  Roboto  en  variantes  delgadas,   ligeras,   regular  y  negrita,   junto  con  un  estilo  de  cursiva  para  cada  variante.  El  marco  también  ofrece  la  variante  Roboto  Condensada  en  pesos  regulares  y  audaces  ,  junto  con  un  estilo  de  cursiva  para  cada  variante.  

Colores  de  tipo  predeterminado  La  interfaz  de  usuario  de  Android  utiliza  los  siguientes  estilos  de  color  por  defecto:  textColorPrimary  y   textColorSecondary.   Para   los   temas   ligeros   utiliza   textColorPrimaryInverse   y  textColorSecondaryInverse.  Los  estilos  de  color  de  texto  de  framework  también  admiten  variantes  para  el  tacto  de  retroalimentación  cuando  se  utiliza  dentro  de  los  elementos  de  interfaz  de  usuario.  

 

Escala  Tipográfica  El  contraste  en  tamaños  de  letra  puede  recorrer  un  largo  camino  para  crear  diseños  comprensibles.  Sin  embargo,   también   muchos   tamaños   diferentes   en   la   misma   interfaz   de   usuario   puede   ser   un   poco  incómodo.  El  framework  de  Android  utiliza  el  siguiente  conjunto  limitado  de  tamaños  de  letra:  

Los usuarios pueden seleccionar un factor de escala de todo el sistema  para  el  texto  en  aplicación  Ajustes.   Para   apoyar   estas   funciones   de   accesibilidad,   la   tipografía   debe   especificarse   en   pixeles   de  escala   independiente   (sp)   siempre   que   sea   posible.   Los   diseños   que   soporten   tipografías   escalables  deben  ser  probados  contra  estos  valores.    

Color  

Usar  colores  primarios  para  enfasis.  Escoja  los  colores  que  vayan  con  su  marca  y  proporcione  un  buen  contraste  entre  los  componentes  visuales.  Note  que  el  rojo  y  el  verde  pueden  ser  indistinguibles  para  los  daltonicos.  

Page 163: Manual Inicio Android (1).pdf

 

  162  

 

Paleta  El  azul  es  el  color  de  enfasis  estandar  en  la  paleta  de  colores  de  Android.  Cada  color  tiene  su  tono  más  oscuro    correspondiente  que  puede  ser  usado  como  un  complemento  cuando  sea  necesario.  

 

 

Iconografía  

 

Un   icono   es   una   gráfica   que   ocupa   una   pequeña   parte   del   espacio   de   la   pantalla   y   proporciona   una  rápida  representación  intuitiva  de  una  acción,  un  estado  o  una  aplicación.  

Al  diseñar  iconos  para  su  aplicación,  es  importante  tener  en  cuenta  que  su  aplicación  se  puede  instalar  en   una   variedad   de   dispositivos   que   ofrecen   una   amplia   gama   de   densidades   de   píxeles,   como   se  menciona  en   la   sección  Dispositivos   y  Pantallas.   Pero  usted  puede  hacer  que   sus   iconos   se   vean  muy  bien  en  todos  los  dispositivos,  proporcionando  a  cada  icono  en  varios  tamaños.  Cuando  su  aplicación  se  ejecuta,   Android   comprueba   las   características   de   la   pantalla   del   dispositivo   y   carga   los   assets  apropiados  para  la  densidad  especifica  para  su  aplicación.  

Page 164: Manual Inicio Android (1).pdf

 

  163  

Dado   que   va   a   entregar   cada   icono   en   varios   tamaños   para   soportar   diferentes   densidades,   las  directrices   de   diseño   que   siguen   se   refieren   a   las   dimensiones   del   icono   en   las   unidades   dp,   que   se  basan  en  las  dimensiones  en  píxeles  de  una  pantalla  de  densidad  media  (MDPI).  

 

Por   lo   tanto,   para   crear   un   icono   para   diferentes   densidades,   debe   seguir   la  relación   de   escala  2:3:4:6:8  entre   los   cinco   densidades   primarios   (medio,   alto,   x-­‐alta,   xx-­‐alta   y   alta,   respectivamente-­‐xxx).  Por  ejemplo,  considere  la  posibilidad  de  que  se  especifica  el  tamaño  de  un  icono  de  lanzador  para  ser  48x48  dp.  Esto  significa  que  la  línea  de  base  (MDPI)  de  activos  es  de  48x48  píxeles,  y  el  asset  de  alta  densidad   (HDPI)   debe   ser   de   1,5   x   de   la   línea   base   en   72x72   píxeles,   y   los   assets   de   x-­‐high   densidad  (XHDPI)  deben  ser  2  veces  la  línea  de  base  a  96x96  píxeles,  y  así  sucesivamente.  

Nota:  Android   también  es  compatible  con  pantallas  de  baja  densidad   (LDPI),  pero  normalmente  no  es  necesario  crear  assets  personalizados  en  este  tamaño  porque  Android  efectivamente  reduce  sus  assets  HDPI  a  la  mitad  para  que  coincida  con  el  tamaño  esperado.  

Lanzador  El  icono  de  lanzador  es  la  representación  visual  de  su  aplicación  en  la  pantalla  de  inicio  o  la  pantalla  “All  Apps”.  Dado  que  el  usuario  puede  cambiar  el  papel   tapiz  de   la  pantalla  de   inicio,  asegúrese  de  que  el  icono  de  lanzador  es  claramente  visible  en  cualquier  tipo  de  fondo.  

 

Dimensiones  y  escala  

• Iconos   del   lanzador   en   un   dispositivo   móvil  deben  ser  48x48  dp  .  

• Iconos   del   lanzador  para   su  visualización  en  Google  Play  debe  ser  512x512  píxeles  .  

 

Page 165: Manual Inicio Android (1).pdf

 

  164  

 

 

 

 

 

 

 

Dimensiones  

• Activo  completo,  dp  48x48    

Estilo  

Utilice  una  silueta  distinta.  Tridimensional,  de  frente,  con  un  ligero  punto  de  vista  como  si  se  mira  desde  arriba,  de  modo  que  los  usuarios  perciben  una  cierta  profundidad  

Page 166: Manual Inicio Android (1).pdf

 

  165  

Action  Bar  Iconos  de  la  barra  de  acción  son  los  botones  gráficos  que  representan  las  acciones  más  importantes  que  las  personas  pueden  tomar  dentro  de  su  aplicación.  Cada  uno  debe  emplear  una  metáfora  simple  que  representa  un  concepto  único  que  la  mayoría  de  la  gente  puede  entender  de  un  vistazo.  

Glifos   pre-­‐definidos   deberían   ser   utilizados   para   ciertas   acciones   comunes   tales   como   "actualizar"   y  "compartir".    

 

 

   

 

 

 

 

 

Dimensiones  y  escala  

• Iconos  de  la  barra  de  acción  para  los  teléfonos  deben  ser  32x32  dp  .  

 

Área  focal  y  proporciones  

• Activo  completo,  dp  32x32  • Plaza  óptico,  dp  24x24  

 

Estilo  

Pictográfico,   plano,   no   muy   detallada,   con  suaves   curvas   o   formas   agudas.  Si   el   gráfico   es  delgado,  girarla   45   °  a   la   izquierda  o   la  derecha  para   llenar   el   espacio   focal.  El   grosor   de   los  trazos  y  espacios  negativos  debe  ser  un  mínimo  de  2  dp.  

Colores  

Colores:  #   333333  Habilitado:  el   60%  de   opacidad    para  minusválidos:  30%de  opacidad  

Colores:  #   FFFFFF  Habilitado:  el   80%  de   opacidad    para  minusválidos:  30%de  opacidad  

   

Page 167: Manual Inicio Android (1).pdf

 

  166  

 

 

Iconos  pequeños/contextuales  Dentro  del  cuerpo  de  su  aplicación,  use  pequeños  iconos  para  acciones  superficiales  y/o  proporcionar  el  estado  de  elementos  específicos.  Por  ejemplo,  en  la  aplicación  de  Gmail,  cada  mensaje  tiene  un  icono  de  estrella  que  marca  el  mensaje  como  importante.  

 

 

 

 

 

 

 

 

 

 

Dimensiones  y  escala  

• Iconos   pequeños   deben  ser  16x16  dp  .  

 

Área  focal  y  proporciones  • Activo  completo,  dp  16x16  • Cuadrado  óptico,  dp  12x12  

 

Estilo  

Neutro,   plana,   y   simple.  Formas   rellenas   son   más  fáciles   de   ver   que   los   trazos   finos.  Utilice   una   sola  metáfora   visual   de   manera   que   un   usuario   puede  reconocer  fácilmente  y  entender  su  propósito.  

Page 168: Manual Inicio Android (1).pdf

 

  167  

 

 

 

 

 

 

 

 

 

 

Iconos  de  notificación  Si  su  aplicación  genera  notificaciones,  proporcionar  un  icono  que  el  sistema  puede  mostrar  en  la  barra  de  estado  cada  vez  que  una  nueva  notificación  está  disponible.  

 

 

Colores  

Utilice   los   colores   no   neutros  con   moderación   y   con   un  propósito.Por   ejemplo,   Gmail  utiliza   amarillo   en   el   icono   de  estrella  para   indicar  un  mensaje  marcado   como   favorito.  Si   el  icono   es   recurrible,   elegir   un  color   que   contraste   con   el  fondo.  

Dimensiones  y  escala  • Iconos   de   notificación   deben  

ser  24x24  dp  .    

Área  focal  y  proporciones  

• Activo  completo,  dp  24x24  • Cuadrado  óptico,  dp  22x22  

 

Page 169: Manual Inicio Android (1).pdf

 

  168  

 

 

 

Consejos  de  Diseño  Estos   son   algunos   consejos   que   pueden   resultar   útiles   a   medida   que   crea   iconos   u   otros   drawables  assets  para  su  aplicación.  Estos  consejos  se  presupone  que  está  utilizando  programa  Adobe  ®  Photoshop  ®  o  algún  similar  de  edición  de  imágenes  raster  y  vector.  

Utilice  formas  vectoriales  cuando  sea  posible  

Muchos   programas   de   edición   de   imágenes   como   Adobe   ®   Photoshop   ®   le   permiten   utilizar   una  combinación   de   formas   vectoriales   y   capas   raster   y   efectos.   Cuando   sea   posible,   utilice   formas  vectoriales   para  que  en   caso  de  necesidad,   los   activos  pueden   ser   ampliadas   sin  pérdida  de  detalle   y  nitidez  de  borde.  

Estilo  

Mantener  el  estilo   llano  y   simple,  utilizando  el  mismo  single,  metáfora  visual  como  su  icono  de  lanzador.  

Colores  

Iconos   de   notificación   deben   ser  totalmente   blanco.   Además,   el  sistema  puede  escalar  hacia  abajo  y  /  u  oscurecer  los  iconos.  

 

Page 170: Manual Inicio Android (1).pdf

 

  169  

El   uso   de   vectores   también   hace   que   sea   fácil   para   alinear   los   bordes   y   esquinas   a   píxel   límites   a  resoluciones  menores.  

Comience  con  grandes  mesas  de  trabajo  

Debido  a  que  usted  tendrá  que  crear  assets  para  diferentes  densidades  de  pantalla,  lo  mejor  es  empezar  sus  diseños  de  iconos  en  grandes  mesas  de  trabajo  con  dimensiones  que  son  múltiplos  de  los  tamaños  de   los   iconos   objetivo.   Por   ejemplo,   los   iconos   del   lanzador   son   48,   72,   96,   o   144   píxeles   de   ancho,  dependiendo   de   la   densidad   de   la   pantalla   (mdpi,   hdpi,   xhdpi   y   xxhdpi,   respectivamente).   Si   dibuja  inicialmente   iconos  de   lanzadores   en  una  mesa  de   trabajo   864x864,   será  más   fácil   y  más   limpio  para  ajustar  los  iconos  cuando  se  escala  la  mesa  de  trabajo  hasta  los  tamaños  de  destino  para  la  creación  de  activos  final.  

Al  escalar,  vuelva  a  dibujar  las  capas  de  mapa  de  bits,  según  sea  necesario  

Si  escalas  una   imagen  a  partir  de  una  capa  de  mapa  de  bits,  en   lugar  de  partir  de  una  capa  vectorial,  tendrán   que   volver   a   dibujar  manualmente   a   aparecer   nítidas   a  mayores   densidades   esas   capas.   Por  ejemplo,   si   un   círculo   60x60   fue   pintado   como   un  mapa   de   bits   para  MDPI   que   tendrá   que   volver   a  pintar  como  un  círculo  90x90  para  HDPI.  

Use  convenciones  de  nombres  comunes  para  los  activos  icono  

Trate  de  nombrar  archivos  para  que  los  assets  relacionados  se  agrupan  dentro  de  un  directorio  al  que  estén   ordenados   alfabéticamente.   En   particular,   ayuda   a   utilizar   un   prefijo   común   para   cada   tipo   de  icono.  Por  ejemplo:  

Tipo de activo Prefijo Ejemplo

Iconos ic_ ic_star.png

Iconos del Lanzador ic_launcher ic_launcher_calendar.png

Iconos de menú y barra de acción iconos ic_menu ic_menu_archive.png

Iconos de la barra de estado ic_stat_notify ic_stat_notify_msg.png

Iconos Tab ic_tab ic_tab_recent.png

Iconos de diálogo ic_dialog ic_dialog_info.png

 

Tenga  en  cuenta  que  no  está  obligado  a  usar  un  prefijo  común  de  cualquier  tipo-­‐hacerlo  es  sólo  para  su  conveniencia.  

 

Page 171: Manual Inicio Android (1).pdf

 

  170  

Crear  un  espacio  de  trabajo  que  organiza  los  archivos  por  la  densidad  

Para   soportar   multiples   densidades   de   pantalla   significa   que   se   deben   crear   multiples   versiones   del  mismo  icono.  Para  ayudar  a  mantener  las  múltiples  copias  de  los  archivos  seguros  y  fáciles  de  encontrar,    se   recomienda   crear  una  estructura  de  directorios  en   tu  espacio  de   trabajo  que  organiza   los   archivos  assets  basados  en  la  densidad  objetivo  

ejemplo:

art/... mdpi/... _pre_production/... working_file . psd finished_asset . png hdpi/... _pre_production/... working_file . psd finished_asset . png xhdpi/... _pre_production/... working_file . psd finished_asset . png

xxhdpi/... _pre_production/... working_file.psd finished_asset.png

 

 

Debido  a  que  la  estructura  del  espacio  de  trabajo  es  similar  a   la  de  la  aplicación,  se  puede  determinar  rápidamente  qué  assets  deben  copiarse  en  el  directorio  cada  recursos.  La  separación  de  los  activos  por  la  densidad  también  le  ayuda  a  detectar  cualquier  variación  en  los  nombres  de  archivos  a  través  de  las  densidades,   lo   cual   es   importante   porque   los   activos   correspondientes   a   diferentes   densidades   debe  compartir  el  mismo  nombre  de  archivo.  

 

 

 

 

 

 

Page 172: Manual Inicio Android (1).pdf

 

  171  

Para  comparar,  aquí  está  la  estructura  de  directorio  de  recursos  de  una  aplicación  típica:  

res/... drawable- ldpi/... finished_asset . png drawable- mdpi/... finished_asset . png drawable- hdpi/... finished_asset . png drawable- xhdpi/... finished_asset . png

Su  imagen  de  marca  

Siguiendo  el  patrón  de  diseño  en  Android  no  significa  que  tu  aplicación  tenga  la  misma  apariencia  que  la  de   las   aplicaciones   de   los   demás.   En   Android,   tu   aplicación   puede   brillar   como   una   extensión   de   tu  marca.  

Color  Usa  el  color  de  tu  marca  para  “Acentuar”,  sobrescribiendo  el  marco  azul  por  defecto  de  los  elementos  de   la   Interfaz   de   Usuario   (UI)   como,   barras   de   progreso,   botones   radio,   diapositivas,   pestañas   e  indicadores  de  scroll.  

Busca  la  oportunidad  de  usar  colores  de  contraste-­‐alto  para  enfatizar,  por  ejemplo,  el  color  de  fondo  de  la  barra  de  acción,  o  un  botón  primario.  Pero  no  te  excedas:  no  todas   las  acciones  son  las  mismas,  así  que  úsalo  solamente  para  una  o  dos  cosas  importantes.  

Cuando  se  personalizan   los  colores,   la  retroalimentación  táctil  debe  de  ser  sutil-­‐  solo   ligeramente  mas  claro  u  obscuro  que  el  color  sin  tocar.  

 

 

Los   cuatro   colores   del   Logo   de   la   Cartera  de  Google,   proporcionan  una  acentuación  agradable,   la   cual   consiste   en   cuatro  puntos   que   aparecen   mientras   el   usuario  introduce  un  PIN.    

Page 173: Manual Inicio Android (1).pdf

 

  172  

 

Logo  El  lanzador  del  icono  de  tu  aplicación  es  la  llave  para  incorporar  tu  logo,  por  que  es  lo  que  los  usuarios  buscaran  y  tocaran  al  empezar  a  utilizar  tu  aplicación.  Tu  puedes  mover  tu   icono  a  través  de  todas   las  pantallas  en  tu  aplicación,  mostrando  en  la  barra  de  acción  el  nombre  de  la  aplicación.  

Otra  consideración  a  tomar  en  cuenta  es  colocar  el  logo  en  tu  icono,  así  como  el  nombre  de  la  aplicación  en  la  barra  de  acción.  

 

La  Aplicación  de  Google   Play  Music,   tiene  un   tema  naranja,   el   cual  es   utilizado  para  enfatizar   la   barra   de   acción   y   para  acentuar   la   pestaña   seleccionada,   el  indicador  scroll  así  como  los  hipervínculos.  

 

�Google  +,  refuerza  su  marca  colocando  su  icono  a  través  de  la  barra  de  acción.  

Page 174: Manual Inicio Android (1).pdf

 

  173  

Iconos  Si  cuentas  con  iconos  que  ya  estas  usando  para  tu  aplicación  en  otras  plataformas  y  estos  a  su  vez  tienen  un   look   distintivo   de   acuerdo   a   tu  marca,   los   puedes   utilizar   también   en   tu   aplicación   Android.   Si   se  toma  en  cuenta  esta  consideración,  tiene  uno  que  estar  seguro  que  el  estilo  de  tu  marca  es  aplicado  a  cada  icono  en  tu  aplicación.  

 

Excepción:   para   cualquier   icono   en   tu   juego   existente   de   iconos   donde   la   simbología   es   manejada  diferente  a  como  se  maneja  en  Android,  usa  los  símbolos  de  Android  para  darle  estilo  a  tu  marca.  De  esa  forma,  el  usuario  entenderá  que  propósito  tiene  el  icono.  Aun  así,  el  icono  se  vera  como  si  perteneciera  a  tu  conjunto  de  iconos  como  parte  de  tu  marca.  

Ejemplo:  

El  icono  normal  para  compartir  con  otras  plataformas  es  la  flecha  hacia  la  derecha  

 

Pero,   ¿qué   pasaría   si   no   tienes   aun   tus   propios   iconos-­‐   por   ejemplo,   si   estas   creando   una   nueva  aplicación  solo  para  Android?.  En  este  caso,  usa  los  iconos  estándar  de  Android.  

 

Ejemplo   del   logo   en   la   barra   de   acción.  Esto   funciona  bien  en   los  casos  cuando  el  logo   corresponde   con   el   nombre   de   la  aplicación.  

Page 175: Manual Inicio Android (1).pdf

 

  174  

Estilos  de  Escritura.  

La  voz  de  Android.  Al  escribir  el  texto  que  aparece  en  su  aplicación,  que  sea  concisa,  simple  y  amigable.  

 Conciso:  

•  Describa  sólo  lo  que  el  usuario  necesita  saber.    

•  Eliminar  la  redundancia,  como  los  títulos  que  reiteran  el  cuerpo  de  un  cuadro  de  información.    

•  Mantener  texto  tan  corto  como  sea  posible.    

Evite  muchas  palabras,  texto  abultado:  

No  hacer:  

Consulte  la  documentación  que  viene  con  su  teléfono  para  futuras  instrucciones.  

 

Hacer:  

Lea  las  instrucciones  que  vienen  con  el  teléfono.  

 

No  proporcione  información  innecesaria  

Desde una pantalla de Asistente de configuración

Accediendo  ...  

El  teléfono  necesita  comunicarse  con    los  servidores  de  Google  para  iniciar  sesión  en  su  cuenta.    Esto  puede  tardar  hasta  cinco  minutos.  

 

 

 

 

 

Page 176: Manual Inicio Android (1).pdf

 

  175  

Desde  una  pantalla  de  Asistente  de  configuración  

Accediendo  ...  

El  teléfono  está  en  contacto  con  Google.    Esto  puede  tardar  hasta  5  minutos.  

 

Simple  

• Utilice  palabras  cortas,  verbos  activos,  y  los  nombres  comunes.  

• Poner  primero  lo  más  importante.  "Carga  frontal"  los  primeros  11  caracteres  con  la  información  más  relevante  en  la  cadena.  

• No  trate  de  explicar  las  diferencias  sutiles.  Se  pierden  en  la  mayoría  de  los  usuarios.  

Centrarse  en  la  preocupación  del  usuario,  no  los  detalles  técnicos  

No  hacer  

Controlar  manualmente  el  GPS  para  evitar  que  otras  aplicaciones  lo  usen  

Hacer  

Para  ahorrar  energía,  apague  el  modo  de  ahorro  de  batería  Ubicación  

Coloque  las  principales  noticias  primero  

No  hacer  

Otras  77  personas  han  hecho  +1  en  esto,  incluyendo  Larry  Page  

Hacer  

Larry  Page  y  otros  76  han  hecho  +1  en  esto  

Ponga  la  meta  del  usuario  primero  

 

 

Page 177: Manual Inicio Android (1).pdf

 

  176  

No  hacer  

Toque  Siguiente  para  completar  la  configuración  mediante  una  conexión  Wi-­‐Fi  

 

Hacer  

Para  finalizar  la  configuración  a  través  de  Wi-­‐Fi,  toque  Siguiente  

 

Amistoso  

• Utilice  contracciones.  

• Hablar  directamente  con  el  lector.  Utilice  "usted"  para  referirse  al  lector.  

• Mantenga  su  tono  informal  y  coloquial,  pero  evite  el  argot.  

Evite  ser  confuso  o  molesto  

No  hacer  

¡Lo  siento!  

La  Actividad  MyAppActivity  (en  la  aplicación    MyApp)  no  está  respondiendo  

Hacer  

MyApp  no  responde  

¿Desea  cerrarla?  

 

Palabras  a  evitar  

No  utilice   Use  

uno,  dos,  tres,  cuatro,  ...   1,  2,  3,  4,  ...  

Page 178: Manual Inicio Android (1).pdf

 

  177  

Aplicación   app  

okay,  ok,   OK  

por  favor,  lo  siento,  gracias   Los  intentos  de  cortesía  pueden  molestar  al  usuario,  especialmente  en  los  mensajes  que  dicen  que  algo  ha  ido  mal.    Excepción:  En  japonés,  "por  favor"  es  obligatorio  y  verbos  imperativos  deben  ser  localizadas  en  consecuencia  (encender  -­‐>  por  favor  encienda).  

hay,  es  y  otros  temas  "desaparecidos"  (improperios  gramaticales)    

Utilice  un  sustantivo  como  sujeto  

abortar,  eliminar,  dar  por  terminado   detener,  cancelar,  finalizar,  salir  

fallar,  fracasado,  un  lenguaje  negativo   En  general,  usar  una  frase  positiva    (por  ejemplo,  "hacer"  en  lugar  de  "no  hacer",  salvo  en  casos  tales  como  "No  mostrar  de  nuevo",  "No  se  puede  conectar",  y  así  sucesivamente.)  

 yo,  mi,  mío   usted,  su,  el  suyo  

¿Está  seguro?  ¡Advertencia!   En  lugar  de  eso  encomendar  a  los  usuarios  la  consecuencia,  por  ejemplo,  "Perderá  todas  sus  fotos  y  los  medios"  

 

De  formato  al  texto  

Capitalización  

• Utilice  mayúsculas  al  estilo  de  oración  para  todas  las  cadenas  de  la  IU:  "Palabras  para  vivir."  

• Utilizar  mayúsculas  en  todas  las  palabras  importantes  en:  

o Nombres  de  la  aplicación  (Calendar,  Google  Drive)  

o Características  con  nombre  (Android  Beam,  Face  Unlock)  

o Los  nombres  propios  (Estatua  de  la  Libertad,  San  Francisco  Giants)  

• Sea   conservador.  No   utilice   mayúsculas   en   palabras   que   no   son   parte   de   un   nombre   rasgo  formal:  

Page 179: Manual Inicio Android (1).pdf

 

  178  

o Bloqueo  de  tarjeta  SIM,  Pantalla  de  Inicio,  no  Sim  Card  Lock.  

Puntuación  

• Período.  No   utilice   un   período   después   de   una   sola   oración   o   frase   que   se   usa   de   manera  aislada,  como  en  un  brindis,  una  etiqueta  o  notificación.  Dondequiera  que  dos  o  más  oraciones  corren  juntas,  utilice  un  punto  para  cada  frase.  

• .   Elipsis  Utilice  el   carácter  de  puntos   suspensivos   (...)   (Opción-­‐;   en  MacOS  y   ...   en  HTML)  para  indicar  

o Incompletitud,  como  una  acción  en  curso  ("Downloading...")  o  el  texto  truncado.  

Que   un   elemento   del   menú   (como   impresión...   o   Compartir...)   conduce   a   una   mayor   UI   implica  decisiones  importantes.  Excepción:  Los  comandos  cuya  redacción  ya  implica  más  (pero  limitado)  interfaz  de  usuario,  tales  como  Buscar  en  la  página  o  Elija  una  fecha,  no  requieren