Introducción al desarrollo de aplicaciones en Android
Temario 1.Introducción 2.El SDK 3.Hello World 4.El ciclo de vida 5.Recursos 6.Layouts y Views 7.Interacción con el usuario 8.Menús 9.Preferencias 10.Intents 11.Depuración 12.El Market
1. Introducción a Android
Introducción Smartphones Android en cifras Historia de Android Funcionamento interno
Smartphones Teléfono Rádio MP3 GPS Cámera Internet Apps
Android en cifras #1 en activaciones ( al día) 23% de la cuota de mercado (finales 2010) apps en el market 100+ modelos de teléfono 40+ modelos de tablet
Android en cifras (cont.) Mòbils al món, segons Gartner (Abril 2011)
Android en cifras (cont.)
¿Qué es Android? Conjunto de software para dispositivos móviles que incluye: Sistema operativo Middleware Aplicaciones Open source Impulsado por Google Basado en Linux y Java
Historia Julio 2005: Google compra Android Inc. Noviembre 2007: Nace la OHA Febrero 2009: Release de 1.1 Abril 2009: Release de 1.5 (Cupcake) Octubre 2009: Release de 2.0 (Eclair) Deciembre 2010: Release de 2.3 (Gingerbread)
Versiones API level 3 (Cupcake) 7 (Eclair) 9 (Gingerbread)
Características Sistema base es Linux Máquina virtual Dalvik Librerías de sistema WebKit SQLite Media codecs Comunicaciones (GSM, bluetooth, wifi) Cámara, GPS, sensores Application framework
Arquitectura
Aplicaciones Java (.apk) Se ejecutan en un espacio aislado (instancia de Dalvik) No hay jerarquía Se comunican a través de Intents El market no es imprescindible
Más información Web oficial Android Wikipedia CatDroid
2. El entorno de desarrollo
Elementos necesarios Eclipse Android SDK Eclipse ADT plugin + ADV Manager
Instalación 1.Preparar el equipo (Instalar Eclipse) 2.Descargar el SDK 3.Instalar el plugin ADT para Eclipse 4.Instalar plataformas y APIs
Catclipse Descargar y abrir Ultimo update: Bolets Barruers Disponible para Windows y Mac, próximamente para Linux
3. Hola mundo
Creación de un nuevo proyecto
Elementos del proyecto nuevo Activity Manifest Resources
Activities Una Activity es una pantalla de la interfaz Las aplicaciones constan de una o más Activity Cada Activity es reponsable de guardar su estado Una Activity se encarga de: Crear una ventana donde colocar la interfaz Gestionar la interfaz Responder a los eventos (onClick, onLongClick, etc).
Una Activity básica
Manifest El Manifest es el archivo donde la aplicación le dice al sistema que elementos requiere para funcionar Siempre debe llamarse AndroidManifest.xml y estar en la raíz del proyecto Entre otras cosas contiene: Atributos de la aplicación y metadatos La declaración de actividades y otros componentes Librerías externas Permisos Se puede editar via GUI o editando el XML
Manifest inicial
Versión de la aplicación VersionCode es importante para el Market VersionName es importante para el usuario y/o nosotros
Definición de la actividad Definimos las actividades y sus intent-filter
Versión del SDK minSdkVersion, maxSdkVersion y targetSdkVersion
Permisos de la aplicación Avisan al usuario de las acciones que realizará la aplicación Listados en:
Recursos Un recurso es un elemento a utilizar durante la ejecución de la aplicación Existen diferentes tipos de recursos: Layouts Imágenes Cadenas de texto Sonidos Colores Temas Animaciones etc
Recursos Se almacenan en la carpeta resources Cada tipo de recurso tiene va en una carpeta específica Utilizan sufijos para determinar que recursos utilizar según contexto (tamaño de pantalla, idioma, orientación, etc.) Nombre en mínusculas La extensión se ignora (mismo nombre, diferente extensión se considera duplicado)
La clase R La clase R es generada y mantenida por el sistema y no debe ser modificada Contiene un identificador (int) único por cada recurso Podemos hacer referencia a un recurso en código por R... Ej.: R.layout.main
Nombrar recursos en XML Para referirnos a un recurso utilizamos la siguiente / Por Para definir un nombre /
Ejemplo
4. El ciclo de vida
Estados de una actividad El sistema gestiona las actividades como una pila Una actividad tiene cuatro estados: Activa: la actividad está en primer plano y tiene el focus (enfoque de usuario). Se encuentra en lo alto de la pila. En pausa: la actividad es visible, pero no tiene el focus. Ej: hay un diálogo sobre ella con el focus retenido. Detenida: La actividad está tapada por otra aplicación. Mantiene sus datos. Destruida: Una actividad detenida ha sido destruida para liberar memoria y ha perdido sus datos. Hay que recrearla completamente.
Ciclo de vida de una actividad
Métodos MétodoDescripciónSiguiente onCreate()Donde se crea la interfaz. Se le proporciona un bundle con su estado anterior. onStart onRestart()Justo antes de un onStart cuando venimos de onStoponStart onStart()La actividad se hace visible al usuarioonResume onStop onResume()La actividad está en primer plano interactuando con el usuario onPause La actividad va a ser detenida. Se utiliza para guardar información onResume onStop La actividad ya no es visible al usuario.onRestart onDestroy Última llamada antes de que la actividad sea destruida. El método isFinishing() nos ayuda a saber si es final o temporal
Otro grafo
Ejercicio (I) Clase android.util.Log Log. (String tag, String message) Métodos: e – error d – debug i – info v – verbose w – warning private static final String TAG = "MyActivity"; Log.v(TAG, "index=" + i);
protected void onDestroy() protected void onPause() protected void onRestart() protected void onResume() protected void onStart() protected void onStop()
5. Recursos
Imágenes Carpeta drawables Tres tamaños: ldpi, mdpi, hdpi Tamañoldpimdpihdpi Relación Launcher36x36 px48x48 px72x72 px Menu36x36 px48x48 px72x72 px Status Bar (<=2.2)19x19 px25x25 px38x38 px Status Bar (>=2.3)12x19 px16x25 px24x38 px Tab24x24 px32x32 px48x48 px
Iconos Simplificados Realísta pero no fotorealista Imágen frontal Iluminación superior
Formatos de imágen Recomendación: PNG-24 para imágenes con transparencias JPG para imágenes sin transparencias
Archivos de cadenas cadena ….
Arrays …
Colores Format: #rgb | #rrggbb | #rrggbbaa #FFF #000 #eb5200 #fff #444
Uso de recursos desde código El objeto R.tipo.id siempre devuelve un entero Para recuperar el recurso en cuestión utilizamos: getResources().get (Integer id) O getResources().getIdentifier(String nombre, String tipo)
7. Interacción con el usuario
Eventos Los layouts generan eventos de tipo onAcción Los eventos son acciones que interrumpen el flujo del código Se generan a partir de acciones externas Para implementar un método onAcción una clase debe implementar la interfaz onAcciónListener Para adjudicar la clase que implmementa el «escuchador» utilizamos el método setOnAcciónListener de la vista
Ejemplo con dos clases public class alHacerClick implements OnClickListener public void onClick(View v){ v.setText("Click aqui!"); }... public class Main extends Activity {... boton.setOnClickListener(new alHacerClick());... }
Ejemplo con la actividad public class Main extends Activity implements OnClickListener public void onClick(View v){ v.setText("Click aqui!"); }... boton.setOnClickListener(this);... }
Múltiples eventos en la misma clase Si tenemos a nuestra clase escuchando más de un evento OnClick, el parametro v nos permite averiguar que view ha disparado el evento. Podemos comparar v.getId() con un recurso public void onClick(View v){ switch(v) { case R.id.btnOk: … case R.id.btnCancel: … } (v.getId()==R.Id.btnOk)
Un brindis con el usuario La clase toast permite lanzar mensajes rápidos Toast.makeText(Context context, int resId, int duration) Toast makeText(Context context, CharSequence text, int duration) Duration: Toast. LENGTH_LONG | Toast.LENGTH_SHORT
Diálogos. setButtons AlertDialog: puede gestionar entre 0 y 3 respuestas AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?").setCancelable(false).setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { MyActivity.this.finish(); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create();
Diálogos. Una lista. final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create();
Diálogos. Checkboxes final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create();
Crear un diálogo personalizado Hemos creado el layout custom_dialog Context mContext = getApplicationContext(); Dialog dialog = new Dialog(mContext); dialog.setContentView(R.layout.custom_dialog); dialog.setTitle("Custom Dialog"); TextView text = (TextView) dialog.findViewById(R.id.text); text.setText("Hello, this is a custom dialog!"); ImageView image = (ImageView) dialog.findViewById(R.id.image); image.setImageResource(R.drawable.android); dialog.show();
Menús
Menús. Archivos de menú … <item /> …
Abrir el menú Sobrecargamos el método onCreateOptionsMenu public boolean onCreateOptionsMenu(Menu menu) Llamamos a GetMenuInflater MenuInflater inflater = getMenuInflater(); Llamamos al método inflate del MenuInflater MenuInflater inflater = getMenuInflater();
Procesar las opciones de menú Sobrecargamos el método public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.settings:... }
9. Preferencias
Archivos de preferencias Layout especializado que permite crear pantallas de configuración de forma rápida. <CheckBoxPreference android:key="music" android:defaultValue="true" /> <CheckBoxPreference android:key="hints" android:defaultValue="true"/>
Mostrar archivo de preferencias public class Prefs extends PreferenceActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); } En el manifest:
Leer y escribir preferencias PreferenceManager.getDefaultSharedPreferences(context)…. getTipo(Nombre, Predeterminado); setTipo(Nombre, Predeterminado);
Gestionar public boolean onPreferenceClick(Preference preference){ if (preference.getKey() == "About"){ Dialog dialog = new Dialog(this); dialog.setContentView(R.layout.about); dialog.setTitle(getResources().getString(R.string.OptionAbout)); dialog.setCancelable(true); dialog.show(); } if (preference.getKey() == "DoLogin"){ findPreference("User").setEnabled( PreferenceManager.getDefaultSharedPreferences(this).getBoolean("DoLogin", false)); indPreference("Password").setEnabled( PreferenceManager.getDefaultSharedPreferences(this).getBoolean("DoLogin", false)); } return false; }
10. Intents
Intents Android se basa en multitud de pequeños componentes Estos componentes se comunican via Intents Mensajes utilizados para notificar a las aplicaciones de eventos Cambios de Hardware. Ej: tarjeta SD insertada. Recepción de datos. Ej: llegada de un sms Eventos de la apliación. Ej: se ha lanzado la aplicación Etc Es posible crear nuestros propio intents
Partes de un Intent Partes básicas La acción: una constante que indica la acción que se lanza. Ej.: VIEW_ACTION, EDIT_ACTION Los datos: uri indicando el recurso asociado. Ej.: content://contacts/people/1 Partes opcionales Una categoría: agrupa el tipo de Intent Un tipo MIME: indica el tipo de recurso si no concemos una uri Un componente: la clase que debe tener el receptor. Obvia las otras propiedades, pero es más frágil. Extras: un Bundle con información extra que el receptor va a necesitar
Ejemplos de Intent ANSWER_ACTION CALL_ACTION DELETE_ACTION DIAL_ACTION EDIT_ACTION FACTORY_TEST_ACTION GET_CONTENT_ACTION INSERT_ACTION MAIN_ACTION: Inicio de aplicación PICK_ACTION: permitir a otras apps elegir contenido de la tuya VIEW_CONTENT: para ver contenido EDIT_CONTENT: para editar contenido
Categorias de Intent ALTERNATIVE_CATEGORY BROWSABLE_CATEGORY DEFAULT_CATEGORY GADGET_CATEGORY HOME_CATEGORY LAUNCHER_CATEGORY PREFERENCE_CATEGORY SELECTED_ALTERNATIVE_CATEGORY TAB_CATEGORY TEST_CATEGORY
Llegando a la actividad adecuada Una actividad debe cumplir tres reglas para responder un Intent La actividad debe soportar la acción especificada La actividad debe soportar el tipo MIME si lo hay La actividad debe soportar TODAS las categorias nombradas en el Intent Uso de Intent-Filter en el manifest
Ejemplo
Iniciar otra Activity Uso del método startActivity(Intent) o startActivityForResult (Intent, int) Podemos pasar parametros con Intent.putExtra(int, ) Recibirlos con getIntent().getExtras().get (clave);
Devolver valores de una Activity Establecemos el valor a devolver con setResult(int resultCode) o setResult (int resultCode, Intent data) La actividad «llamadora» implementa el método onActivityResult(int requestCode, int resultCode, Intent data) resultCode puede ser uno de estos valores: RESULT_CANCELED RESULT_OK RESULT_FIRST_USER