
A continuación podréis encontrar una serie de códigos de ejemplo que me han ido haciendo falta en mis proyectos de desarrollo de aplicaciones móviles con Android. Espero que os sean de ayuda.
Para más información sobre el desarrollo Android:
Guía de referencia de desarrollo de aplicaciones móviles Android
Constantes
Podemos almacenar todas las constantes a utilizar en la aplicación dentro de una clase que luego utilicemos en el resto de clases. Suele ser general escribir en nombre de la variable en mayúsculas.
public class Constants { public static final float VIEWPORT_WIDTH = 5.0f; public static final String REST_URL = "http://www.ejemplo.com/api"; }
Logs personalizados
Nos permite crear una clase propia que sea la que genere los logs de la aplicación. De esta manera, al pasarla a producción sólo tendremos que deshabilitar.
public class MyLog { // Cambiar a 'false' para deshabilitar el Log de la aplicación static final boolean DEBUG = true; public static void i(String tag, String string) { if (DEBUG) android.util.Log.i(tag, string); } public static void e(String tag, String string) { if (DEBUG) android.util.Log.e(tag, string); } public static void d(String tag, String string) { if (DEBUG) android.util.Log.d(tag, string); } public static void v(String tag, String string) { if (DEBUG) android.util.Log.v(tag, string); } public static void w(String tag, String string) { if (DEBUG) android.util.Log.w(tag, string); } }
Back Button
Para sobreescribir el funcionamiento del botón "Vovler atrás" podemos utilizar el siguiente código.
Fuera del método onCreate()...
@Override public void onBackPressed() { // Asignar la acción necesaria. En este caso terminar la actividad finish(); }
Up Button
Para habilitar el botón Up dentro del Toolbar de una actividad necesitaremos el siguiente código o sobreescribir el funcionamiento del mismo.
Dentro del método onCreate()...
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarSobreNosotros); if (toolbar != null) { setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setTitle(getResources().getString(R.string.app_name)); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Asignar la acción necesaria. En este caso "volver atrás" onBackPressed(); } }); } else { Log.d("SobreNosotros", "Error al cargar toolbar"); }
Fuera del método onCreate()...
@Override public boolean onNavigateUp() { // Asignar la acción necesaria. En este caso terminar la actividad return true; }
Pero si queremos realizarlo en PreferencesActivity tendremos que sobreescribir el siguiente método.
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { startActivity(new Intent(this, MainActivity.class)); return true; } return super.onOptionsItemSelected(item); }
Crear elementos gráficos desde código
Podemos crear los elementos gráficos de la aplicación desde el código, sin necesidad de crearlos en los layouts XML. Tendremos que cargar el layout principal, que ese sí debe existir previamente y sobre él cargar los elementos.
setContentView(R.layout.activity_main); // Hay que asignarle un ID al LinearLayout en XML, que por defecto no lo tiene LinearLayout LinearMain = (LinearLayout) findViewById(R.id.LinearMain); crearLayoutConImagen(LinearMain, R.drawable.facebook, "http://www.facebook.com");
void crearLayoutConImagen(LinearLayout ly, int res_img, String text){ // Parámetros a asignar al layout LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); // Crear layout contenedor LinearLayout contenedor = new LinearLayout(new ContextThemeWrapper(this, R.style.DarkText)); contenedor.setLayoutParams(params); contenedor.setOrientation(LinearLayout.HORIZONTAL); // Crear imagen ImageView valueIV = new ImageView(new ContextThemeWrapper(this, R.style.DarkText)); valueIV.setImageResource(res_img); // Crear texto TextView valueTV = new TextView(new ContextThemeWrapper(this, R.style.DarkText)); valueTV.setText(text.toString()); valueTV.setLayoutParams(params); // Añadir los elementos imagen y texto al layout contenedor contenedor.addView(valueIV); contenedor.addView(valueTV); // Añadir layout contenedor al layout principal creado en XML de la Actividad ly.addView(contenedor); }
Tratar archivo con contenido JSON
Cómo descargar un fichero JSON de Internet y posteriomente tratarlo para leer su contenido.
try { // Hacer la conexión y leer el contenido línea a línea URL url = new URL("http://www.ticarte.com/rest/10"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; StringBuilder content = new StringBuilder(); while ((line = reader.readLine()) != null) { content.append(line); } // Crear un objeto del contenido JSON completo JSONObject jsoncompleto = new JSONObject(content.toString()); // Comprobar si existe un elemento if (jsoncompleto.has("acontecimiento")) { // Crear un objeto JSON a partir de dicho elemento JSONObject jsonacontecimiento = new JSONObject(jsoncompleto.getString("acontecimiento")); // Recuperar un elemento del objeto anterior Log.d("JSON", (jsonacontecimiento.has("nombre")) ? jsonacontecimiento.getString("nombre") : "No existe nombre"); if (jsoncompleto.has("eventos")) { // Crear un array JSON a partir de un elemento que sea array JSONArray jsoneventos = new JSONArray(jsoncompleto.getString("eventos")); // Recorrer el array JSON para recuperar sus elementos for (int n = 0; n < jsoneventos.length(); n++) { JSONObject jsonevento = jsoneventos.getJSONObject(n); Log.d("JSON", jsonevento.getString("nombreevento")); } } else { Log.d("JSON", "No existe acontecimiento"); } } catch (Exception e) { Log.d("JSON", e.toString()); }
AdMob: Solicitar anuncios de prueba
Cuando estamos probando la aplicación en desarrollo, es mejor no mostrar anuncios verdaderos para evitar hacer clicks erróneos en ellos y que Google nos pueda cancelar la cuenta. Así que solicitaremos a Google que nos muestra anuncios de prueba.
// Sustituir "ABCDEF012345" por el ID de vuestro dispositivo // que ee obtiene del logcat en Android Studio AdRequest adRequest = new AdRequest.Builder() .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .addTestDevice("ABCDEF012345") .build();
Abrir el fichero que se recibe desde un Intent
Podemos recibir un archivo de datos desde cualquier otra aplicación definiendo un Intent-filter en la nuestra.
// Recibir el Intent Intent receivedIntent = getIntent(); // Recibir la acción String receivedAction = receivedIntent.getAction(); // Si es una acción de enviar desde otra APP if(receivedAction.equals(Intent.ACTION_SEND)){ Log.d("demo", "Action SEND"); // Recibir la URI del archivo Uri data = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); String path = data.getPath(); try { // Abrir el fichero InputStream fis = getContentResolver().openInputStream(data); // Utilizar el fichero XmlPullParserFactory xppf = XmlPullParserFactory.newInstance(); xppf.setNamespaceAware(false); XmlPullParser xpp = xppf.newPullParser(); xpp.setInput(fis,null); // Cerrar el fichero fis.close(); } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } } // Si es una acción de abrir la APP directamente else if(receivedAction.equals(Intent.ACTION_MAIN)){ Log.d("demo", "Action MAIN"); }
Pruebas de unidades locales e instrumentadas
Prueba de unidad local
import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class PersonTest { private Pregunta p; @Before public void setUp() { this.p = new Pregunta( "Enunciado", "Categoría", "Respuesta", "Respuesta", "Respuesta", "Respuesta", "" ); } @Test public void personCategoria_isCorrect() { assertEquals(true, this.p.setCategoria("Categoria")); assertEquals(false, this.p.setCategoria("Categoria*")); } }
Prueba de unidad instrumentada contra SQLiteOpenHelper
import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import static org.junit.Assert.assertEquals; @RunWith(AndroidJUnit4.class) public class ModelTest { // Repositorio extends SQLiteOpenHelper private Repositorio repositorio; @Before public void setUp(){ InstrumentationRegistry.getTargetContext().deleteDatabase(Constantes.getNombreDB()); repositorio = Repositorio.getInstance(InstrumentationRegistry.getTargetContext()); } @After public void tearDown() { repositorio.close(); } @Test public void crudDB() { Pregunta p_nueva = new Pregunta( "Enunciado", "Categoría", "Respuesta", "Respuesta", "Respuesta", "Respuesta", "" ); assertEquals(true, repositorio.insertar(p_nueva)); ArrayList<Pregunta> preguntas = repositorio.recuperarPreguntas(); assertEquals(1, preguntas.size()); assertEquals("Enunciado", preguntas.get(0).getEnunciado()); Pregunta p2 = new Pregunta( "1", "Enunciado2", "Categoría2", "Respuesta2", "Respuesta2", "Respuesta2", "Respuesta2", "" ); assertEquals(true, repositorio.actualizarPregunta(p2)); preguntas = repositorio.recuperarPreguntas(); assertEquals(1, preguntas.size()); assertEquals("Enunciado2", preguntas.get(0).getEnunciado()); assertEquals(false, repositorio.borrarPregunta(100)); assertEquals(true, repositorio.borrarPregunta(preguntas.get(0).getCodigo())); preguntas = repositorio.recuperarPreguntas(); assertEquals(0, preguntas.size()); } }
Prueba de unidad instrumentada con Espresso
/* Esperar a que se cierre una actividad */ try { Thread.sleep(5000); } catch (InterruptedException e) { System.out.println("Error en sleep"); } /* Se abre listado y pulsamos botón */ ViewInteraction floatingActionButton = onView(withId(R.id.fab)) .perform(click()); /* Se abre formulario y rellenamos campos */ // Campo de texto ViewInteraction textInputEditText = onView(withId(R.id.artistText)) .perform(click()) .perform(scrollTo(), replaceText("Nombre"), closeSoftKeyboard()); // Campo spinner ViewInteraction switch_ = onView(withId(R.id.switch2)) .perform(scrollTo(), click()); ViewInteraction appCompatSpinner = onView(withId(R.id.spinner)) .perform(scrollTo(), click()); DataInteraction materialTextView = onData(anything()) .atPosition(1); materialTextView.perform(click()); // Campo calendario ViewInteraction calendarImageView = onView(withId(R.id.imageDateForm)) .perform(scrollTo(), click()); ViewInteraction materialButton = onView( allOf(withId(android.R.id.button1), withText("OK"), childAtPosition( childAtPosition( withClassName(is("android.widget.ScrollView")), 0), 3))); materialButton.perform(scrollTo(), click()); /* Hacemos clic en el botón y se cierra formulario */ ViewInteraction materialButton2 = onView(withId(R.id.save)) .perform(scrollTo(), click()); /* Se abre listado y pulsamos en el elemento de la lista */ ViewInteraction recyclerView = onView(withId(R.id.recyclerView)) .perform(actionOnItemAtPosition(0, click())); /* Se abre formulario y comprobamos campos */ ViewInteraction editText = onView(withId(R.id.artistText)) .check(matches(isDisplayed())) .check(matches(withText("Nombre")));
Android: Códigos de ejemplo escrito por Rafa Morales está protegido por una licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional