Castellano

La navaja suiza de Android

Un pequeño listado de aplicaciones y sitios indispensables cuando trabajas con Android. Lo que yo llamo la navaja suiza:

Flat UI Colors: Listado de colores “planos” para utilizar en nuestras apps. Selecciona formato, haz clic en un color y ¡voilà! lo tienes en el portapapeles.

Android cheat-sheet for Graphic Designers: Una chuleta exhaustiva sobre cosas relacionadas con el diseño de apps. Para los que no somos capaces de recordar cosas como el tamaño de los iconos en cada densidad.

Android Holo Colors: Selecciona color, versión, controles y automáticamente nos genera un zip con los drawables y styles necesarios.

Android Asset Studio: Impresionante conjunto de generadores de assets para Android

Parcelabler: Hacer un objeto parcelable es bastante lento y tedioso. Con esta página, tan sólo pega el código de tu clase y a cambio la recibes completamente “parcelablizada”.

Android Layout Finder: Uno de mis favoritos. Pega un layout, elige los widgets/layouts que quieres y te genera el método findViews() de un layout, o todo un Adapter con ViewHolder y todo en el que sólo hay que rellenar el pintado de datos. Gracias a @EsteveAguilera por encontrarnos esta joya.

Android Layout/Style XML Converter: Muy útil para extraer estilos de un layout.

Jsonschema2Pojo: Genial página que nos propone un pojo a partir de un json. Además, permite añadirle anotaciones para Gson o Jackson.

Roman Nurik’s View Server: Pequeña librería que nos permite ejecutar el Hierarchy Viewer contra nuestra app aunque el dispositivo no esté rooteado.

¿Conoces más? Pues comparte en los comentarios e ire ampliando la lista.

Actualización 24 de julio

Algunas cosillas más que he ido obteniendo:

DPI calculator for Android: un rápido conversor entre DPIs. También disponible como extensión de Chrome.

Gradle, please: un buscador de dependencias en formato Gradle. Muy util para incluir rápidamente a los sospechosos habítuales.

Android drawable generator: esta web genera el tag para un objeto button y el drawable necesario. Multitud de parametros personalizables. Lástima que no haga también los múltiples estados.

APK Downloader: se supone que permite descargar apks no disponibles en tu país desde Google Play, pero nunca he conseguido hacerlo funcionar, ya que tenían muchas limitaciones de número de descargas diarias. Según dicen, ya está solventado.

Android Design Tips: una chuleta con cosas básicas de diseño y UI (tamaños, márgenes, etc). También incluye un conversor de DPIs

The Android Arsenal: repositorio de librerías y componentes clasificados por categorías.

WSDL2Code: últimamente me está tocando atacar servidores SOAP. Esta ultra-útil página genera la capa cliente de Android a partir de un WSDL. Generar, copiar, y utilitzar.

Actualización 3 de agosto de 2014

Mockup Phone: un sistema rápido de hacer mockups de capturas de pantalla. Rápido y fácil:

En busca de la arquitectura de Android perfecta II: arquitectura general de una app

¡Hola!

Hoy voy a hablar de la arquitectura que suelo seguir en mis apps. Para empezar, unas cuantas normas básicas que siempre sigo:

  • Estoy hablando de apps cliente de una api REST (o similar). Esto no sirve para juegos ni para según que cosas.
  • Todos los datos van a ser persistidos. ¡Si respetas a tu usuario, persiste los datos!
  • La base de datos local no es una base de datos per se, es una caché. La base de datos de verdad está en el servidor, y nosotros sólo tenemos una parte de ella. Tengamos esto siempre en cuenta.
  • Me permito ignorar algunas veces las formas normales en pro de la simplicidad y el rendimiento. Total, sólo soy una caché, la base de datos buena y con datos normalizados está en servidor.
  • Las pantallas de splash en apps de Android son el demonio
  • La guía de estilo es sagrada. Sólo se puede romper para innovar y mejorar. Todavía no he conocido a nadie capaz de hacerlo. Hacerlo diferente no es innovar. Hacerlo como en iPhone no es innovar.
  • Mis reglas son mías y me las salto cuando quiero

Arquitectura general por capas

Durante un par de años trabajé con Code Igniter, un excelente Framework MVC sobre PHP (sí, tengo un pasado como programador de PHP, era joven, necesitaba el dinero). Y yo lo siento, pero por más que miro, no creo que Android sea MVC. Esto es discutir el sexo de los ángeles, hay gente que está de acuerdo conmigo, y gente que no, así que vamos a partir de la idea de que nuestra arquitectura NO se va a basar en MVC.

En cuanto a capas hablamos, yo divido la aplicación en Frontend y Backend, o como les suelo llamar, ui y sdk.

De hecho, en grandes proyectos suelo montar el sdk en un proyecto librería y la ui en un proyecto principal. Esto ayuda mucho a separar estas dos capas y a distribuir el trabajo.

En la capa ui tengo todo aquello encargado de gestionar la interfaz: activities, fragments, views, adapters, etc. Todo ello objetos consumidores de datos. Cae alguna cosilla más que a veces tiene que estar aquí por la idiosincracia de Android aunque no sean ui tal cual, como el objeto Application, Notifications, el Push, etc.

Por otro lado, en la capa de sdk (que tiene la chicha) tengo lo que gestiona los datos: beans, clientes, ContentProviders y tareas (y algunas cosillas más del tipo helpers).

La capa UI

De esta hablaremos otro día a fondo con ejemplos, de momento ahí van algunas generalidades y normas que uso.

Todos los elementos de esta capa los incluyo dentro del paquete ui. Así tendremos ui.activity, ui.fragment, ui.adapter, ui.view, etc.

Todas las clases tienen como sufijo lo que son, por ejemplo MainActivity, ForlayosAdapter, etc.

Cada elemento tiene un conjunto de constantes públicas, finales y estáticas que empiezan por EXTRA con los nombres de los parámetros que pueden ir en el bundle del intent de llamada.

Los Intents entre activities y fragments no se mandan objetos enteros (y mucho menos arrays). Sólo se mandan el id del objeto. Así por ejemplo, si tengo una actividad (o fragment, ahora da igual) ProductListActivity con una lista de productos, al seleccionar uno invoco a la siguiente actividad ProductActivity sólo le paso el id, y esta segunda invoca al content provider para que le retorne el registro y lo lee. Si además los datos pueden cambiar durante su visualización por elementos externos, utilizo un loader para mostrar el detalle.

Los adapters SIEMPRE con ViewHolder.

La capa SDK

Esta capa es la que se encarga de la entrada y salida de datos hacia el servidor y de la persistencia de la misma. Aquí u gráfico con los elementos principales:

android architecture

Repasemos los paquetes que suelo crear y que hay en cada uno:

  • bean: pues aquí van todos los objetos de datos. ¿qué tu le llamas DTO, domain o algo así? pues bién, no me pelearé por eso, pero lo que no hago son distinciones. Cada vez intento que sean los más POJO posibles y no les hago ni getters ni setters, vamos, que son estructuras tontitas con anotaciones para la deserializacíon JSON.
  • client: aquí todos los clientes. Son las representaciones del los servicios web. Por ejemplo, una clase LoginClient invoca al servicio de login, gestiona la respuesta y nos la devuelve procesada. Uso una estructura de IntentService tonto que invoca al servicio web que el client le pasa como parámetros. Ya hablaremos de esto en otro artículo. La gracia del sistema es que haces los client como churros. Aquí se produce la serialización/deserialización a JSON (o lo que toque).
  • model: aquí todo el modelo de datos, en la raíz coloco el contrato de datos, el conjunto de constantes que definen tablas, campos y entidades del content provider. En algunos casos cuando las aplicaciones son muy grandes, separo el contrato de base de datos y el de content provider, pero ojo que entonces el mantenimiento es farragoso y complicado.
  • model.content: los content provider, siguiendo la estructura del artículo anterior con DespicableContentProvider y MinionContentProvider
  • model.cursor: aqui tengo un CursorHelper por entidad. Básicamente se encargan de pasar de registro del cursor a objeto y viceversa
  • model.db: el DatabaseHelper y similares.
  • service: aquí va el IntentService que invocan los clientes, así como cualquier otro servicio que pueda necesitar.
  • task: son procesos atómicos que invocan clientes y ContentProviders. Por ejemplo, la típica tarea de UpdateProductsTask invoca a GetProductsClient, hace un delete sobre el Content Provider de productos y luego un bulk insert. Este proceso tiene una salida indicando si ha ido bien o mal.

El meollo de esto está también en mi librería de acceso a servicios web llamada Rarest. Teneis info en www.rarestandroid.com.

Ale, el próximo día veremos un lindo ejemplo con todo esto.

En busca de la arquitectura Android perfecta I: Despicable Content Providers

Desde hace tiempo vengo buscando cual puede ser la mejor arquitectura de una aplicación Android. Ojo, no tiene por que ser la mejor en cuanto a rendimiento o velocidad, pero tiene que dar un buen rendimiento, ser lo más Android-compliant y sobre todo, fácil de replicar. Mi objetivo no es más que sentar las bases para nuevos proyectos (tanto profesionales como personales) y decir “pues yo trabajo así”. Tengo muchas ideas en la cabeza, pero sin compartirlas y discutirlas, pues no hay manera, así que voy a ir compartiendo algunas de estas ideas, y a ver que sucede.

Hoy empezaré por los ContentProviders. Voy a asumir que ya sabes que es y como funciona un ContentProvider y el acceso a SQLite. Si no lo sabes, mírate el tutorial del amigo Vogella en http://www.vogella.com/articles/AndroidSQLite/article.html. Si os fijas en el punto 9.4 del tutorial, vereis que el estructura el ContentProvider de la siguiente manera por cada una de las operaciones (query, insert, delete y update):

Odio el switch. Me parece la estructura más fea y poco mantenible que existe. Además, en el ejemplo, sólo utiliza dos URLs, pero imaginad una aplicación donde tengo 20 entidades. Vamos, lo que viene siendo una clase Dios.

Mi propuesta para esto es lo que denomino el DespicableContentProvider. ¿Y por qué lo llamo así? Por que tiene MinionContentProvider (lo se, don’t use cute names, pero no pude resistirme, y la analogía se entiendo muy bien). Si no sabes de que va lo de Despicable y Minions, mira esto: http://www.youtube.com/watch?v=jzpOLs1t8Hg

Todo el código base, tanto del DespicableContentProvider como del MinionContentProvider están en https://gist.github.com/sergiandreplace/8165986 y son bonicos, libres y distribuibles.

Antes de todo, establezcamos como uso los ContentProvider y cual es mi approach:

  • El ContentProvider (CP a partir de ahora) lo veo parecido a una api web.
  • Cada url representa una entidad.
  • Las url estan formadas por content://<nombre de la autoridad>/entidad[/#id].
  • Las url acabadas en id estan pidiendo un elemento específico, y las conocemos como tipo Item. Las otras son tipo Dir (por coherencia con los tipos MIME)
  • El tipo mime será vnd.android.cursor.{dir|item}/vnd.{AUTORIDAD}.{ENTIDAD}. Mis CP suelen ser internos no publicados, así que el tipo MIME me da un poco igual.
  • El consumidor del CP no sabe NADA de la base de datos. En realidad, lo monto para que el único que tenga acceso a la bd sea el CP. Incluso los contratos son diferentes, uno para la bd y otro para el CP (a menos que sean algo muy pequeño).
  • Cuando una petición es de tipo Item, es decir, pido uno con un id espécifico, los parametros de filtrado son ignorados (si ya pido uno ¿para que quiero filtrar?)

La idea básica de esta estructura es que cada Minion sabe hacer Insert, Update, Delete y Query de una entidad para Item o para Dir (no ambos). Veamos un ejemplo:

Como veis, he hecho tres cosas, por un lado getBasePath que devuelve la url específica de la entidad, getType, que devuelve el nombre básico para construir el tipo MIME si queremos, y hemos implementado cuatro funciones muy parecidas a las de un ContentProvider normal. Las diferencias son, que por un lado recibo el objeto db para poder lanzar las aplicaciones y no notifico el cambio al acabar.

Uno de tipo Item no tiene mucha diferencia:

Diferencias:

  1. La clase en singular (soy así…)
  2. El path incluye el /# según la sintaxis del UriMatcher
  3. En cada operación, decidimos ignorar los parámetros que recibimos y filtramos por el id de la ruta a piñón.
  4. Decido que el insert de Item no se puede hacer. No hay razón para esto, era por poner un ejemplo. La otra opción sería cambiarlo en el contentValues por el de la url antes del insert. Ahí ya depende de vuestro modelo.

¿A que es facil? Pues creariamos uno de estos por cada entidad Dir o Item  y ale.

Una vez hechos, hay que implementar el Despicable. Que ya vereis que facil:

El método GetAuthority sólo devuelve el nombre de la autoridad que vamos a utilizar. Es usado por la clase padre. El método getDB() debe devolver un objeto Database con el que trabajar. Y el método recruitMinion se encarga de añadir cada uno de los Minions a la colección instanciando las clases que heredan de MinionContentProvider.

Y ya. Mirad que bonico todo.

Ahora nuestro CP ofrece todas las operaciones en cada minion, incluso, de regalo, un bulkInsert que ejecuta un loop de inserts dentro de una transacción.

Ah, suelo añadir estos dos métodos de regalo en el ContentProvider:

Son muy útiles en los contratos y los CursorHelper, que es algo de lo que hablaré el próximo día.

Me encantaría recibir comentarios al respecto y ver como vosotros abordáis el problema. Y cualquier sugerencia, ya sabes, será bienvenida.

Mails para mi concuñado II – Internet no existe

Segundo mail que le mando a mi cuñado. Parece que el primero le gustó, así que sigo taladrando. Creo que en el próximo le meteré el vi por vena, a ver si sobrevive (mwahahaha)…

Internet no existe. Bueno, existe, pero no es “nada”, es una amalgama de muchas cosas.

Cuando hablamos de redes informáticas se suelen dividir en tres tipos, lan, wan, y man la primera (local access network) es la red de tu casa o la mia, la segunda (wide access network) es la de por ejemplo una empresa o entre varios edificios, etc. La tercera (metropolitan access network) es una red accesible en toda un ciudad (ej: la wifi de bcn). Aunque esta división ha quedado un poco anticuada.

Pues bién, Internet no es más que un conjunto de wanes, lanes y manes. Pero muchas. Muchisimas. Cuando nació en los 50 existían mapas con las redes y los ordenadores puestecitos, pero enseguida fué indibujable debido a la gran cantidad.

¿Y como se aclaran los ordenadores en estas lanes, wanes y manes? pues con protocolos. Un protocolo no es más que un conjunto de reglas que especifican como comunicarse. Hay protocolos para aburrir, y suelen estar especificados en reglas definidias por comités como el IEEE (esto igual te suena de electróncia), la ISO, o los conocidos RFP (request for proposal) RFC (Request for comment).

Hay protocolos para enrutar señales y protocolos para dibujar en pantalla. ¿Cómo nos aclaramos? pues como dije en el mail anterior, por CAPAS. TODO son capas. Las redes se suelen especificar a partir de un sistema de capas llamados OSI (de la ISO, el que inventó la siglas ese dias estaba de cachondeo). Esto divide la red en siete capas (el próximo dia te las recito de memoria, que me las se). Al final son teoricas, y cada protocolo de red establece un poco las que quiere, pero siempre con estas en mente.

Las capas de más abajo, son más “cercanas” al hardware, las de más arriba son más cercanas a “a la persona” (esto hay que tomarlo con pinzas, que estoy siendo super generalista). ¿Te suena esto de alto y bajo nivel?

Así, por ejemplo, el router con el que te conectas al interné, actua en capas bajas, mientras que firefox actua en capas medias-altas (vas pillando la idea?)

A la hora de resolver problemas ayuda mucho moverse por capas, de arriba a abajo o viceversa (depende del caso) para ser ordenador. Por ejemplo, si no puedo navegar por internet, antes de mirar si mi proveedor de internet me la esta jugando, miro si puedo comunicarse con el router. Si esto no sucede, ya no hace falta que mire más “arriba”, el problema está en mi router, mi ordenador o entre ambos.

Entonces, tenemos cosas abajo, y cosas arriba funcionando. Las de arriba se basan en las de abajo. Si mi tarjeta de red (capa 0 o 1, según) está rota, pues no puedo ver páginas web (capa 7).

Además, cuando dos ordenadores se comunican en Internet, se comunican de capa a capa. Es decir, si estoy usando un servicio de capa 6 para conectar a otro ordenador, pues la “señal” baja a la capa 0, llega al otro ordenador, y vuelve a subir a la capa 6. En teoría, es una comunicación de capa 6 a capa 6.

En la práctica, no hablamos de capas, si no de servicios. Algunos servicios serán más altos y otros más bajos, pero son servicios.

Cuando vemos una página web, estamos haciendo uso del servicio HTTP, cuando chateas por Google Talk, estamos usando el servicio XMPP, cuando envias un mail, estas usando el servicio SMTP, y cuando recibes, el POP3 o el IMAP, depende del formato de correo. Hay hasta aburrir. TODO lo que usas en internet son servicios.

Vamos a empezar a poner nombres a las cosas.

Lo más básico que tenemos es TCP/IP. Es lo que se conoce como el protocolo de red, y todos los servicios que he comentado, funcionan sobre él. Existen otros protocolos de red, pero en la actualidad, casi que sólo se utiliza este (hablo de uso común, cosas raras hay a miles).

En redes TCP/IP, cada conexión tiene una (o más) dirección de red. Está dirección de red está formada por 4 bytes (32 bits) y se suele mostrar como cuatro cifras de 1 byte, por ejemplo 192.168.1.1, conocidas como dirección ip (de TCP/IP v4, las de v6 son diferentes).

Tengo un libro entero de 500 páginas SÓLO hablando de esto. Es complejo, denso, y no espero que entiendas la mitad de lo que explico, pero es bastante entretenido.

Entonces, si yo quiero acceder a un servicio en una máquina, necesito saber tres cosas:

1. Su dirección IP
2. El servicio que estoy usando
3. el puerto

Anem a pams.

1. Abre la terminal y haz “ping www.google.com”

Verás como te dice algo así como “reply from 173.194.41.244” (el número puede cambiar). Ese es un truco para saber la dirección ip de una dirección.

¿Recuerdas que he dicho que todo eran servicios? pues aquí hemos usado dos. Por un lado, el DNS, que traduce nombres a direcciones IP. Si no fuese por el, no tendriamos urls (el tipico www.hhh.jjj…). Y además, el ICMP que es un protocolo de control. Vamos, el ping. Esto sirve pa preguntar a una maquina “Hooola.. hay alguien?”, y la máquina dice “síiiii”. Tonto, pero es la forma que tenemos de ver si una máquina puede ver a otra.

Vale, ya tenemos el punto 1 resulto.

2. El servicio
Pues depende de lo que quiera de www.google.com. Normalmente, empezar por www ya indica que quiero acceder a web, pero en realidad se especifica con el HTTP:, lo que ocurre es que el navegador da muchas cosas por sentado, y si le pides google.com, ya presupone que en realidad lo que queres es http://www.google.com

3. El puerto
Es otra forma de saber el servicio a utilizar, cada servicio tiene un puerto estándar, que no es más que un número. Por ejemplo, la web es el 80, el ftp el 21, el smtp el 32 (digo de memoria), etc, etc. Tambien tienes hasta aburrir.

Mu bien, ya sabemos acceder a un servicio.

Cuando accedemos a un servicio, se dice que yo soy el cliente, y la máquina al otro lado es el servidor, de ahí lo de arquitectura cliente-servidor. Existe otro tipo, que es el P2P (peer-to-peer) o distribuido. En este tipo de servicios no hay “un” servidor, si no que el trabajo se distribuye entre todos los clientes (típico caso, el torrent o el emule).

Entonces, que necesito en mi ordenador para usar un servicio determinado…. pues un cliente. Firefox (y chrome, y IE, y todos los navegadores) son en realidad clientes web (y FTP y alguna cosilla más). Thunderbird es un cliente de correo.

Si quiero utilizar el servicio de torrent, necesito un cliente de torrent. O sea, un programa.

No creas que eso de servidor implica mega ordenadores y esas cosas, tu pc hace de servidor cuando por ejemplo, compartes una carpeta, o cuando ves una peli via dlna (otro protocolo, en este caso de transmision de media) uno es el servidor y el otro el cliente (llamados library y renderer en este caso).

El transmission hace un poco de trampa, por que puedes tenerlo en dos formas. Una como aplicación de escritorio, que es lo que te viene. El problema es que sólo funciona cuando lo abres, y eso no te interesa. También existe una versión daemon. Los daemons o demonios (en windows se llaman servicios) son programas que se ejecutan independientemente del usuario, es más, se inician ANTES de que inicies sesión.

La gran ventaja del transmission daemon es que está ahí paradico, y cuando tiene trabajo se arranca. ¿Y como se configura? pues tocando ficheros de configuración.Y para ver lo que está descargando? pues resulta…. que el transmission daemon es un cliente de torrent y además un servidor web (tachan) y puedes ver lo que hace iendo a una url determinada (que has configurado en el ficherito de marras).

Buf, que rollo macabeo he soltado. Cuando empieces a digerir esto, te mando más.

Mails para mi concuñado I – ¿Qué es un sistema operativo?

Mi concuñado es un tio majete. Y quiere aprender cosillas de informática. Como es médico (o MIR, o residente, o pokemon de agua, no se, no entiendo las diferencias) y chupa guardias, pues trastea con un portatilillo guarro que tiene, y no tiene miedo de nada. Como se lo curra y pregunta BIEN (algo que escasea), pues de vez en cuando le mando mails tocho con explicaciones muy bestias. Como creo que pueden servir a más gente, los comparto, y a ver que tal.

DISCLAIMER: se que técnicamente no estoy siendo preciso, y que incluso digo medias verdades, pero esto está escrito para gente NO técnica que no diferencia entre Ethernet y XBox, así que prefiero hacerlo divertido que exacto.

Ahí va el primer mail

Empecemos por el principio. Tienes que entender que es un Sistema Operativo (SO).
Un SO es el encargado de construir elementos abstractos que te permitan interactuar con el equipo. Por ejemplo, cuando hablamos de un fichero ¿de que hablamos exactamente? ¿de una entrada en la tabla de archivos del SO? ¿en un conjunto de bytes? ¿en unos sectores y pistas del disco? ¿en un conunto de partículas en la superficie de un disco que están cargados magneticamente con una carga positiva o negativa? ¿microsurcos en un dvd? pos eso, que no lo sabemos, el SO se encarga de crear un elemnto abstracto llamado fichero (que en realidad no existe).
Los SO pueden ser de más alto nivel (piensan más como la persona) o de más bajo nivel (piensan más como la máquina). Ser de alto o bajo nivel no es bueno ni malo, son formas diferentes de trabajar. Mac es de muy alto nivel, Windows algo menos (pero están ahí ahi), linux es de muy bajo nivel, pero implementa escritorios que suben mucho el nivel, y mac en el fondo, es un bsd (un unix) que a la que abres la terminal, bajas de nivel drásticamente.
Android, por ejemplo, es un linux al que se le ha puesto una capa por encima que sube MUCHO el nivel, de hecho, en los SO moviles apenas hay gestión de ficheros (desde el punto de vista del usuario estándar).
El tema este de capas es muy importante en la informática en general, todo se hace por capas, todo. Es imposible abarcar la complejidad de un proyecto de SW sin dividirlo en capas. Incluso yo cuando hago cosas para el movil, divido mis apps en capas.
Tener un SO u otro, también determina que apps podemos ejecutar. Por ejemplo, si coges un EXE de windows y lo intentas ejecutar en linux o mac, te dirà que tururu. SI intentas instalar un DMG en windows se te reirá en la cara. Por que cada SO entiende los programas de una manera determinada. Es verdad que hay formar de “saltarse” esto, por ejemplo, WINE, permite cargar apps de windows en linux.
Claro, a la hora de programar, esto es un coñazo, por que si tengo que hacer una aplicación que funcione en diferentes SO, tengo que hacerlo por cada uno de ellos, y esto se intenta evitar. El conocido DODM (Develop Once, Deploy Many). Ahí entran lo que se conocen como lenguajes interpretados. Por ejemplo, Java. Las apps de Java, se ejecutan sobre una JVM (máquina virtual de java), y es este jvm lo que cambia por cada SO (por eso hay que bajarse java para XX antes de ejecutar una app java). Lo mismo sucede con Python, que es un lenguaje interpretado. (Aquí los puristas me saltarian al cuello, pero para lo que quiero explicar, me sirve)
¿Y que tiene que ver este rollazo con los que has visto? pues mucho.
Por ejemplo, vas a descargar Sickbeard TPB y te sale esto: http://sickbeard.com/downloads.html
¿Ein? ¿como que Windows o Github o Python? Calma, todo tiene explicación
Los usuarios de Windows están “mal” acostumbraditos (y los de mac) a bajarse un instalador, siguiente, siguiente, siguiente y pa casa. Bueno, pues en el mundo *nix (linux, unix, xenix, etc) esto no es así. Lo normal es que te bajes el código fuente y lo compiles/ejecutes a mano, como los hombres (aunque con los años también se ha simplificado mucho).
Estos de sickbeard son majetes de decir “hola monguer de windows, te hemos hecho un instalable para que te puedas defender tu solito”
Ah, pos que bien ¿y que otras opciones tengo?
Pues instalarte python (en muchos linux ya viene), bajarte el código fuente y currartelo tú.
Github es un repositorio de apliaciones open source. Ahí la gente sube el código fuente de cosas (apps, librerias, modulos, etc) y cualquiera puede bajarlo. Incluso yo tengo código: https://github.com/sergiandreplace)
El problema que habrás tenido, es que el señor de TPB pasa de los de windows. El que quiera series, que se moje el culo.
Y ahí es donde entra la terminal. Los hombres con pelo en el pecho hacen las cosas a pelo, y las hacen metiendo comandos.
Tienes que entender que la terminal es un programa, igual que el escritorio, igual que xbmc e igual que todo. Tu en linux configuras que app quieres que aparezca al arrancar/iniciar sesión. Y puede ser cualquiera de ellos.
TRUCO DE MASTER 1:
Linux es multiusuario, quicir, que varios usuarios pueden trabajar a la vez, y para cambiar de usuario, cambias de “pantalla”. Eso se hace pulsando CTRL+ALT+F#
Las de F1 a F6 son de texto, la F7 a F9 son gráficas. Pulutant, para meter todo el churro de comando en una terminal, según como es más rápido pulsar CTRL+ALT+F1 y meterse en una sesión de terminal que abrir la app. Sobretodo en XBMCBUNTU que no tienes app de terminal. Luego pa volver, pues CTRL+ALT+F7 y listos.
Y ahora llegamos a la parte de los usuarios.
Linux es muy seguro, y es por ello que no deja que los usuarios toquen nada “by default”. Para tocar algo, hay que elevar la sesión. Esto MacOsX y Windows lo han acabado copiando (mejor o peor)
En linux, el usuario con más privilegios es root, por lo tanto, dirias, pos nada, hago login como root y fuera. NOOORL, eso caca, de hecho, muchas distribuciones ni te dicen el pwd del root.
Lo que tienes que hacer es convertirte en un sudoer. Normalmente tu usuario con el que has instalado en un sudoer.
Los sudoers pueden lanzar comandos como root.
Por eso estas todo el rato metiendo comandos sudo estos o sudo lo otro.
Ahí venía el chiste este:
Sandwich
si haces “shutdown 0” te dice que no
si haces “sudo shutdown 0” apaga la máquina en 0 segundos
Obviamente, para evitar que alguien pueda hacer sudos por que tu te dejes la máquina desatendida, el sudo pide password otra vez.
Ale, luego más

Uri que te uri

Hola

Me estaba peleando con la camara de Android, y tras “invertir” todo el dia he descubierto una cosilla que a lo mejor os interesa saber.

Estaba llamando a un intent de camara para que me devolviese un fichero, para ello, debemos pasarle un extra con nombre MediaStore.EXTRA_OUTPUT que contenga un objecto Uri apuntando al nombre.

Pues bien, hay varias formas de generar un Uri con métodos de clase:

a) Uri.fromFile(File newUri)

b) Uri.parse(String newUri)

Parece que ambos deberian generar el mismo contenido, pero…. CATACROCKER!

Uri.parse(“/mnt/sdcard/img/photo.jpg”) genera un objeto uri descafeinado. Vamos, le rellena el campo Uri.mPath y pa casa.

Uri.fromFile(new File(“/mnt/sdcard/img/photo.jpg”)) genera un objeto uri con todas sus propiedades y vitaminas.

Pues si al intent de la cámara le pasas el Uri descafeinado, no funciona, si le pasas el segundo (creado con FIle) funciona perfectamente.

Nada, sólo quería compartirlo.

Update 28-agosto-2012

Como dice kix2902 en los comentarios, el Uri.parse funciona con un path del tipo “file://…”.  Lo que no entiendo es por que con una uri incorrecta parsea mal y se queda tan ancho en vez de lanzar una excepción como toca, o al menos no aparece una indicación en la documentación al respecto.

 

Seguimos con Maven. Plantillas.

¡Hola!

Yo sigo erre que erre con Maven. El siguiente paso ha sido crearme una plantilla que contenga la info común en los proyectos Android. Esto es, por supuesto, aplicable a cualquier tipo de proyecto. Los pasos son:

Crear un proyecto nuevo para el POM

En Eclipse creamos un proyecto nuevo de tipo Maven, Maven Project y hacemos clic en siguiente.

Seleccionamos Create a simple project (skip archetype selection) y next.

Introducimos la información del pom. En este caso hablamos de como nos referiremos a nuestra plantilla. Por ejemplo:

  • GroupId: com.sergiandreplace.template
  • ArtifactId: android
  • Version: 0.0.1-SNAPSHOT
  • Packaging: pom <– Aquí está la clave del asunto!!!
  • Name: Android POM template

Por último hacemos clic en Finish y nos creará el proyecto.

Crear el POM base

En este caso, el pom es parecido al que creamos en el último post sobre maven, pero con algunos cambios.

Y con esto tendriamos la plantilla. Básicamente, he extraido los valores que cambian de proyecto en proyecto a variables, y además he creado una sección con valores por defecto.

Para publicarlo en nuestro repo local, tan sólo debemos ejecutar un mvn install y el sólo nos lo añadirá.

Ya tenemos la plantilla lista.

Heredar la plantilla

Ahora en nuestro proyecto Android con maven (recordad el mavenize project) tan sólo necesitamos tener el siguiente pom:

Como veis, aquí le indico, por un lado, de que proyecto hereda la configuración, y por otro lado que valores debe utilizar para las variables. Si  mirais el POM efectivo, vereis que contiene toda la configuración correctamente establecida.

Consideraciones finales

Recordad que si trabajais en equipo, es necesario que todo el mundo tenga las mismas plantillas o la podeis liar muy parda. En ese caso, os recomiendo tener algún repositorio de Maven (p.ej.: Nexus) y tener las plantillas publicadas en el servidor.

El uso de plantillas hace más sencillo el aplicar nuevas configuraciones y opciones a los proyectos existentes, y nos permite configurar los proyectos nuevos de forma más rápida.

Ale, gozadlo.

Ejemplos y comentarios del Barcelona Startup Weekend Bootcamp

El pasado sábado tuve la suerte de poder impartir el Bootcamp del Barcelona Startup Wekeend. Durante esta sesión, vimos una introducción al servicio de GAE para montar un servidor rest y como utilizar la libreria AndroidAnnotations para hacer aplicaciones Android de forma rápida.

Por razones que no acababa de entender, no conseguimos hacer funcionar la libreria AndroidAnnotations como cliente rest, y como sospechaba que era un tema de librerias, prometí mirarlo con calma y postear un proyecto que funcionase.

Después de mucho investigar he encontrado la causa de los problemas y he podido solucionarlos.

Usar Maven con Android

La idea de este artículo es presentar los pasos necesarios para configurar Eclipse para utilizarlo con Maven en proyectos Android. Estos pasos son:

Descargar herramientas

Descargamos Eclipse si no lo tuviesemos (en mi caso utilizo Eclipse Classic 3.7.2) desde http://www.eclipse.org/downloads/.

Configuramos el sdk de Android i el ADT (http://android.com)

Descargamos Maven desde http://maven.apache.org/download.html (para el ejemplo usamos 3.0.4)

Asumimos que instalamos las herramientas en D:eclipse, D:android-sdk-windows y en D:maven si tu ruta es diferente, cambialo donde toque.

Instalar plugin de Eclipse para Maven (m2Eclipse)

Desde http://www.eclipse.org/m2e/download/ podemos ver las diferentes rutas de descarga.

En nuestro caso, en Eclipse, vamos a Help, Install New Software… e introducimos http://download.eclipse.org/technology/m2e/releases como url.

Configurar el plugin de Maven

En mi caso configuro siempre lo siguiente:

En la venta de preferencias (Window, Preferences) seleccionamos MavenInstallations. Allí podemos añadir el ejecutable de Maven. Así nos aseguramos que el plugin y la linea de comandos utilizan la misma versión.

Instalar el conector de Android para Maven

Ahora hay que decirle al plugin que “entienda” los proyectos de Android. Para eso tenemos que instalar el conector de Android. Dentro de la pantalla de preferencias, en MavenDiscovery, hacemos clic en Open Catalog. Se nos abrirá el listado de conectores.

Buscamos ‘Maven Integration for Android Development Tools’ (escribe Android y acabarás antes) y lo instalamos.

Ya estamos listos para trabajar con Maven para Android.

Configurar un proyecto para usar Maven

Nunca he conseguido que creando un proyecto nuevo de Maven directamente funcione. Lo que hago es crear un proyecto normal, y luego, podemos hacer clic con el botón derecho sobre la raiz del proyecto, y seleccionar Configure, Convert to Maven Project.

Así se nos transformará en un proyecto de Maven, pero nos toca configurar el POM. Básicamente, utilizo la siguiente plantilla:

Y aquí algunos de los valores a configurar:

  • GROUP_ID_DEL_PROYECTO: la ruta canónica del paquete (p.ej.: com.sergiandreplace)
  • NOMBRE_DEL_PROYECTO: el identificador del paquete que completa la ruta canónica.
  • VERSION_DE_ANDROID: la versión de Android que utilizamos en la app. Ojo que no valen todas, sólo aquellas que estén en el repositorio. Podemos consultar la lista aquí: http://mvnrepository.com/artifact/com.google.android/android
  • NOMBRE_FINAL_APK: pues eso, el nombre que tendrá el fichero final cuando compilemos.
  • VERSION_DE_API: versión de api utilizada para compilar en formato numérico. P.ej: 7 para 2.1

Si ahora ejecutamos desde la linea de comandos en la carpeta del proyecto

Se nos instalaran las dependencias necesarias
Ahora si ejecutamos

Se nos compilará e instalará en los moviles disponibles desde adt.

También podemos hacer un compilado/ejecución de toda la vida en Eclipse.

Quedan cosas por configurar (donde hacer deploy, certificados, etc) pero esto ya depende de cada proyecto, aquí sólo he mostrado lo mínimo para empezar.

Jugando con Unity

Llevo unos dias jugueteando con Unity (no, el infecto escritorio de Ubuntu no, me refiero a la herramienta de creación de aplicaciones 3d).

La verdad, es indecentemente fácil hacer cosas con ella. Subo un ejemplillo para que veais que se hace en un par de horitas con algo de scripting.

1 of 3
123