Monday, December 27, 2010

Finding hardware/software properties at runtime

Right now I am working in an app that needs to detect hardware properties at runtime to change it's behavior.
Some possible examples:
  • We might want to add some arrow keys to our screen if the used doesn't have a way to navigate.
  • We need to know user's locale.
  • We are doing a game and we want to provide some in screen controls if the user doesn't have a keyboard.

For this kind of needs Android provides a class called Configuration.
Let's say we want to detect which kind of navigation the user has in his device.

We will get the device's value doing:


getResources().getConfiguration().navigation

and then we need to compare it against the different constants in the Configuration class.
public static final int NAVIGATION_UNDEFINED = 0;
public static final int NAVIGATION_NONAV = 1;
public static final int NAVIGATION_DPAD = 2;
public static final int NAVIGATION_TRACKBALL = 3;
public static final int NAVIGATION_WHEEL = 4;

Some examples in different devices:

Motorola Droid: navigation=2 (NAVIGATION_DPAD)
Nexus One: navigation=3 (NAVIGATION_TRACKBALL)
Galaxy S: navigation=1 (NAVIGATION_NONAV)

Friday, December 24, 2010

Review Nexus S

Nota: Este blog post lo hizo Pabloks. Compañero de la facu que está arrancando en el mundo Android. Bienvenido :)

Tuve la suerte de estar en NY el 16 de Diciembre y conseguir, felizmente, el último Nexus S del local. Debo admitir que en un momento me sentí en Argentina: El día anterior pasé por un local de Best Buy y pregunté si ya tenían en stock los teléfonos, la respuesta fue un "no, hubo un problema con el envío y los teléfonos llegan el 20 y salen a la venta el 22". Por suerte, como buen argentino, no me dí por vencido y pasé por otro local, y ahí me dijeron que el teléfono estaba y que a las 8.01 am del 16 se empezaban a vender.

Por suerte llegué al local, habían 2 personas (me esperaba una cola en la cuadra como si tocasen los teen angels en corrientes) y pude conseguir el teléfono. Felicidad suprema :)

Aclaración: Actualmente tengo una Blackberry de Nextel por lo tanto voy a describir diferencias entre una Blackberry y el Nexus S. A su vez comentarios sobre el Nexus One, Galaxy S e IPhone 4.


Hardware

El Nexus S (GT-I9020) basicamente es una versión del Galaxy S (GT-I9000). A lo cuál casi trae las mismas características (el menú inferior difiere, el Galaxy S trae slot para micro SD y Radio FM, y otras pequeñeses).

Las características principales son:

  • Procesador 1 GHz Hummingbird
  • 512 MB RAM
  • 16 GB de memoria interna
  • Pantalla de 4'' SUPER AMOLED con soporte mDNIe (mobile Digital Natural Image engine)
  • Camara posterior de 5 MP (graba a 720p)
  • Camara frontal VGA
  • Wi-Fi b/g/n con soporte DLNA
  • Bluetooth
  • NFC (Network Field Communication)
Para más detalles ver la descripción oficial.

Con respecto al Nexus One no tiene características muy distintivas. Las diferencias que se pueden apreciar son:
  • Pantalla de 4 pulgadas con tecnología SUPER AMOLED
  • Mejorado el táctil de la pantalla
  • Cámara frontal
  • NFC
Si están interesados en una buena comparación de ambos vean este artículo realizado por pocket-lint.

NFC

Al principio no tenía idea que era y, honestamente, estaba muy entretenido probando apps del Market para investigarlo :P. Cuestión que estaba el otro día jugando, apoyo el celular en la billetera y sale un cartel "Tag Detected". Vuelvo a probar y lo mismo. Qué es entonces? El NFC es un protocolo basado en una interfaz inalámbrica que brinda la posibilidad de comunicar 2 dispositivos inalambricamente. Resumiendo, el celular lee las tarjetas de proximidad! (en realidad lee frecuencias RFID) La idea es que uno pueda ir pasando por distintos lugares, con objetos, teléfonos, etc. y que el celular te vaya marcando los tags respectivos! Por ejemplo... Supongamos que ambos teléfonos traen NFC, se podría armar que acercando ambos teléfonos automáticamente te brinde los datos de la otra persona.

mDNIe

Mobile Digital Natural Image engine es una tecnología creada por Samsung que está siendo utilizada actualmente sus televisores LCD y LED haciendo que las imágenes sean más nítidas y claras.

Software

Realmente Gingerbread no trae cambios significativos en la UI respecto a FroYo. La mayoría de las mejoras que se realizaron son de las librerías internas del SO logrando mejores velocidades de respuestas. El teclado fue mejorado incorporando, primero, la posibilidad de detección de palabra a medida que se va escribiendo (al estilo de la app SwiftKey) y, segundo, la capacidad de hacer selección de texto por medio del multitouch (se selecciona los rangos del texto) para poder copiar y pegar.

Contras

Una de las principales contras que le encuentro al teléfono es la falta del slot SD para poder expandir la memoria (a pesar que el Galaxy S trae). Otra desventaja, para nosotros los argentinos, es que actualmente únicamente está la versión para T-Mobile, a lo cuál las bandas de 3g de nuestro país no funcionan con el teléfono. Actualmente estoy probando el teléfono con un chip 3g usando la conexión EDGE y por lo pronto funciona bien para todo lo que es mail, chat, twitter, facebook, etc. Debo admitir que al touch todavía le falta un poquito. Hay veces en que no responde al mando o la transición es lenta (en comparación al IPhone 4 o Ipad).

Pros

Es el Nexus S! Viniendo de una blackberry me gustó prácticamente todo. Es muy intuitiva la usabilidad, el market está lleno de aplicaciones para lo que se te ocurra, la posibilidad de tener skype (la mayoría no lo va a pensar como un pro, pero en blackberry no existe), esta muy bien lograda la integración de todo lo que es social media, y más! El agregado del NFC tiene muy buen potencial y con el uso del giroscópio se pueden lograr apps muy interesantes (Google Sky Map!). Todavía no usé el soporte de VoIP/SIP pero ya de por sí es interesante.

Conclusión

Esta semana estoy sacando la linea para regalar la blackberry :P

¿Es posible comprar una tablet Android en Argentina?



Semanas atrás
Salió un blog post en celularis que mencionaba que la galaxy tab iba a estar disponible en Claro. Más tarde, un blog post por Movistar.

Domingo 12 de Diciembre
Sale en el diario La Nación la publicidad de claro mencionando que el galaxy tab va a estar disponible!


Por más que llamé nadie sabía nada en Claro.

Martes 14 de Diciembre
Estuve paseándome por sucursales de claro averiguando hasta que entré a una que tenía una chica vestida de samsung. Antes de sacar número le pregunto:
- Hola, ¿tienen la galaxy tab acá?
- Sí. Avisame cuando te toque que te la llevo para ver.
- Genial!

Llega mi turno, le hago una seña a la flaca y tengo la siguiente conversación:
- Tomá. Acá lo tenés.
- mmm... Esto es un galaxy S. Yo quiero el tablet de 7'.
- Este es el único galaxy que existe.
- Nop
- ¿Me vas a decir a mí que trabajo para samsung?
- Ok, ya te vas a acordar de mí :)


Seguí llamando a claro y también me pasó algo muy gracioso:
- Hola, ¿ya se puede comprar el galaxy tab?
- ¿Qué?
- Hola, ¿ya se puede comprar el galaxy tab?
- Señor, no lo escucho bien. ¿De dónde me está hablando?
- De mi celular con claro!
- Debe tener algun problema.
- No sé, decimelo vos!

Miércoles 15 de Diciembre
Me entero que ni Claro ni Movistar tiene tarifa plana de 3g. El único que tiene es personal con black desde 200$.

Martes 21 de Diciembre
Movistar me confirma por twitter que todavía no está disponible la galaxy tab.
BTW tienen un servicio muy copado de twitter @MovistarArg. Es mucho mejor que el viaje sin retorno entre derivaciones de claro.

Voy a claro para averiguar un cel para mi novia. Quería el Samsung i5500. La oferta de claro no nos convenció y lo compramos liberado. Nada de permanencias y por valores similares.

Ahí pregunté nuevamente por el tab y me dijeron que podía pasar mañana que ya habían llegado pero que todavía no estaban a la venta.

Por fin!

Miércoles 22 de Diciembre
Voy a claro pido el galaxy tab.

Detalles de la compra:

* $120 por mes
* 2 años de permanencia
* 3GB de transferencia (ASTERISCO GIGANTE: Ver final de la historia)
* $3099

Acepto y espero a que haga todos los papeles.
40 mins más tarde le pido que lo siga que vuelvo en un rato que tenía que volver al trabajo.

Cuando vuelve me dicen:
"Mirá me confundí el plan de datos es de 600MB no de 3GB"

Hice un par de cuentas y le dije:
- Ok. Damelo. Voy a hacer esto:
* Doy de baja mi línea
* Pongo la línea del tab en mi cel
* Compro una sim de internet que es más barata.

- Puede ser, pero tené en cuenta que el galaxy tab viene con micro sim.
- Bueno, dale para adelante!

(Unos minutos más tarde...)
- Mirá no tengo sistema. ¿Podés pasar mañana?
- No, gracias. Cancelá todo.

Conclusiones:
* Comprar una tablet en Argentina es imposible.
* Me quedé sin auto-regalo de navidad
* Lamentablemente la posta es comprar liberado.

Feliz navidad a todos!

Wednesday, December 15, 2010

Concurso NDrive. Tengo cinco licencias de Argentina para regalar!



Concurso NDrive


La gente de NDrive se contacto conmigo hace unos días para ofrecerme la posibilidad de repartir cinco licencias de NDrive para el mapa de Argentina.



Pasos a seguir para ganar la licencia:

  1. Ir al market y descargar NDrive.
  2. Probar la aplicación y encontrar el feature que más les guste.
  3. Darle puntaje y poner un comentario en el Android Market.
  4. Poner un comentario en esta entrada explicando cómo esa feature elegida te va a ayudar en tu vida cotidiana.
Se eligirá al ganador en base a la creatividad, originalidad y humor.

Algunos ejemplos:
  • Voy a usar el modo peatón para no perderme cuando tenga que ir al super chino.
  • Voy a usar el pad de mi nexus one para controlar el mapa 3d como controlo la Matrix (?)

El concurso arranca hoy Jueves 16 y termina el Miércoles 22.
Los ganadores serán anunciados el Jueves 23.

Qué estás esperando? Descargala ya!



Saturday, December 4, 2010

Flof + Layar = Flof-Layar!

Hace un tiempo venía con ganas de probar Layar.

¿Qué es Layar?
Layar es una empresa holandesa con bases en Amsterdam. El producto es un navegador de capas (layers) para encontrar varios temas por medio de tecnología de realidad aumentada.

Para probarlo necesitaba una fuente de puntos de interés. Aprovechando que estaba cursando una materia con Juan F. Codagnone (@juam) le pedí si me podía dumpear la db de Flof.

¿Qué es Flof?

Flof es una colección de lugares catalogados por usuarios en forma libre. Así como es posible guardar páginas favoritas, con flof se puede guardar, compartir y descubrir lugares dentro de una gran comunidad.

Flof es una aplicación colaborativa: la información disponible es el resultado de la interacción de los usuarios con la aplicación y de los datos que éstos aportan al catalogar e ingresar puntos en el mapa (lugares).

El servidor a usar es GAE.
Mientras esperaba que Juan me pase los puntos de Flof tuve la oportunidad de cursar Cloud Computing. Buenísimo! Dos pájaros de un tiro. Termino de aprender GAE y liquido el proyecto Flof-Layar. La materia la dio Miguel Saez (@masaez) empleado de Microsoft.

La idea de hacerlo en GAE se esfumó en un segundo. Hicimos el tp para Windows Azure :(
Es la primera vez que codeo algo en plataforma Windows. Como todo, encontré cosas muy buenas (ej: las búsquedas espaciales en sql azure) pero por otro lado me encontré con cosas muy malas (ej: Launching Azure debug from Visual studio and bind in * instead of 127.0.0.1)

Les dejo un par de screenshots de mi cel con la app corriendo:







Lamentablemente no lo puedo dejar el layer subido porque las cuentas que nos dieron de azure tienen sólo un mes de validez.
Me quedará terminar la versión de GAE y colgarlo :)

Wednesday, December 1, 2010

Creating a Shadow for Robolectric in 6 steps

Some days ago I asked for a pull request in Robolectric's github repo. I finished my ShadowConnectivityManager. The discussion can be read here. I will explain how I did it so someone else can continue creating Shadows :).

Why do I need a ShadowConnectivityManager?
The app we are doing right now requires internet to work so we did a nice SplashScreen that checks if internet is available.
If there is internet go to the main Activity, else show a cute msg saying that you don't have internet.

So we created a class called ConnectionStatus which has a method:

boolean isOnline();


NOTE: We should have created the test first but since we are also giving a try to roboguice we did the code before the test.


public class ConnectionStatus implements IConnectionStatus {

private ConnectivityManager cm;

@Inject
public ConnectionStatus(ConnectivityManager cm) {
this.cm = cm;
}

public boolean isOnline() {
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}

return false;
}
}


Instead of doing:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
we can inject it :)

Ok, time to test. When I try to inject a ConnectivityManager to a test there was an exception saying that my variable should have a @Nullable annotation.

Conclusion:
Null instance in test scope == "Robolectric needs your help! Create a Shadow object!"

STEP 1: Understand how Android works
Robolectric basically mocks Android's behavior. You need to understand how it works for you to mock it correctly.

In our case:

* You use an Android's context to get the ConnectivityManager which is a SystemService.
* You ask the ConnectivityManager to give you the ActiveNetworkInfo.
* The class NetworkInfo has a method isConnectedOrConnecting() which will determine if your are online or not.

STEP 2: Decide how the Shadow should be used

We want to be able to set if we are connected or not and check if our ConnectionStatus class is returning things accordingly.
To do that we will leave a flag inside the NetworkInfo's Shadow to let the user decide what it should return.

STEP 3: Code the Shadow
In our case we need to code ShadowConnectivityManager and ShadowNetworkInfo

// With the Implements annotation we tell Robolectric which Android's class this is shadow of.
@Implements(ConnectivityManager.class)
public class ShadowConnectivityManager {

// We will hold here an instance of the ActiveNetworkInfo.
private NetworkInfo networkInfo;


// All methods that exists in the real Android's class and overridden by the shadow
// must have an Implementation annotation. I don't know what for :(
@Implementation
public NetworkInfo getActiveNetworkInfo() {
return networkInfo == null ? networkInfo = newInstanceOf(NetworkInfo.class) : networkInfo;
}
}

Ok, my first big doubt was: "Ok, I need to return a NetworkInfo but I need it to be a shadow, how do I do it?"
That what Robolectric.newInstanceOf() is for :)



@Implements(NetworkInfo.class)
public class ShadowNetworkInfo {

private boolean isConnected = true;

@Implementation
public boolean isConnectedOrConnecting() {
return isConnected;
}

/**
* Non-Android accessor
* Sets up the return value of {@link #isConnectedOrConnecting()}.
*
* @param isConnected the value that {@link #isConnectedOrConnecting()} will return.
*/
public void setConnectionStatus(boolean isConnected) {
this.isConnected = isConnected;
}
}


Pretty easy as well. We have an Non-Android accesor that we will use to set the wanted connectivity status.


STEP 4: Modify Robolectric.java

* Add your Shadow classes to the list in the getDefaultShadowClasses() method.
* Create the shadowOf methods:

public static ShadowNetworkInfo shadowOf(NetworkInfo instance) {
return (ShadowNetworkInfo) shadowOf_(instance);
}

public static ShadowConnectivityManager shadowOf(ConnectivityManager instance) {
return (ShadowConnectivityManager) shadowOf_(instance);
}

* Optional: I needed to modify ShadowApplication as well.

Why?
Application is in charge of the getSystemService's method.
We need to modify it to return our ShadowConnectivityManager just adding this:

if (name.equals(Context.CONNECTIVITY_SERVICE)) {
return connectivityManager == null ? connectivityManager = newInstanceOf(ConnectivityManager.class) : connectivityManager;
}



STEP 5: Test your Shadow
I will just copy and paste the test we did. It's quite simple:

@RunWith(WithTestDefaultsRunner.class)
public class ConnectivityManagerTest {
private ConnectivityManager connectivityManager;
private ShadowNetworkInfo networkInfo;

@Before
public void setUp() throws Exception {
Robolectric.bindDefaultShadowClasses();
Robolectric.application = new Application();
connectivityManager = (ConnectivityManager) Robolectric.application.getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = Robolectric.shadowOf(connectivityManager.getActiveNetworkInfo());
}

@Test
public void getConnectivityManagerShouldNotBeNull() {
assertNotNull(connectivityManager);
assertNotNull(connectivityManager.getActiveNetworkInfo());
}

@Test
public void networkInfoShouldReturnTrueCorrectly() {
networkInfo.setConnectionStatus(true);

assertTrue(connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting());
}

@Test
public void networkInfoShouldReturnFalseCorrectly() {
networkInfo.setConnectionStatus(false);

assertFalse(connectivityManager.getActiveNetworkInfo().isConnectedOrConnecting());
}
}


STEP 6: Share it!
Ask for a pull request!


How did our testcase end up being?


@RunWith(XTestRunner.class)
public class ConnectionStatusTest {

@Inject
private ConnectivityManager cm;

@Test
public void connectionStatusShouldBeFalseWhenOffline() {
ConnectionStatus connectStatus = new ConnectionStatus(
getConnectivityManager(false));
assertFalse(connectStatus.isOnline());
}

@Test
public void connectionStatusShouldBeTrueWhenOnline() {

ConnectionStatus connectStatus = new ConnectionStatus(
getConnectivityManager(true));
assertTrue(connectStatus.isOnline());

}

private ConnectivityManager getConnectivityManager(boolean connected) {

ShadowNetworkInfo ni = Robolectric.shadowOf(cm.getActiveNetworkInfo());
ni.setConnectionStatus(connected);

return cm;
}
}



Conclusion:

While I code this simple Shadow for ConnectiviyManager someone else created a Shadow for AsyncTask and SQLite!
Shadows amount is increasing version by version => Android TDD is getting easier and easier thanks to Robolectric.

Robolectric it's a very cool fw. I consider myself a newbie to it but I could place some commits to it ;)
The support in the mailing list is excellent and I guess in the next release we will be able to add mvn support completely.

What are you waiting to give it a try?

Sunday, November 28, 2010

Robolectric with Roboguice in the TDD mix

My last blog post was about a little skeleton I did with every piece of fw I needed to start a new Android application using TDD. Phil Goodwin post a comment saying I should try Robolectric. So here's my blog post about it :)

Robolectric is a unit test framework that de-fangs the Android SDK jar so you can test-drive the development of your Android app. Tests run inside the JVM on your workstation in seconds.


So before adding it to my skeleton I did a little test. In one of my projects I have an util class that reads some cars from a json file located at /res/raw. You can see how it went in this mail list thread.

Ok, next step to place Robolectric inside my skeleton was to mavenize it.
I opened an issue, created a new mail list thread and started working on it. Fortunately Christian Williams was interested and we started hacking the pom together.

At the time I am writing this the mvn support is working and we are missing the upload to mvn central. I guess next release of Robolectric will have the jar available through mvn central.

For the test project I was using robotium and Android-mock. I will remove them since Robolectric is ready to join my test project's pom as a dependency :)

Shorts steps to install robolectric in your mvn repo.

* Clone https://github.com/mosabua/maven-android-sdk-deployer
* mvn clean install
* Clone https://github.com/pivotal/robolectric/tree/master
* mvn clean install

My test-app's pom.xml looks like this. Finally tests don't need an android emulator to run.

My new project uses Roboguice and the first Activity we made is a SplashScreen. The layout is just a RelativeLayout with a background set, an ImageView with the app's logo in the center of the screen and a progressBar. The Activity's code looks like this:

public class SplashActivity extends GuiceActivity implements ISplashView {

@InjectView(R.id.splash_progress_bar)
private ProgressBar mProgressBar;

@Inject
private SplashPresenter mPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter.setView(this);
setContentView(R.layout.splash);
}
....
}



So our first test in the application was the simple shouldHaveALogo() mentioned in the robolectric's user guide. We struggle a little with @mgv making Roboguice with Robolectric work together but we did it. This is how:

To make it work, we needed to extend RobolectricTestRunner.

public class XTestRunner extends RobolectricTestRunner {

public XTestRunner(Class testClass) throws InitializationError {
super(testClass, "../X-app/AndroidManifest.xml",
"../X-app/res");
}

@Override
protected Application createApplication() {
return new IoCApplication();
}
}


IoCApplication is just the class that extends GuiceApplication. Yep, the one that overrides addApplicationModules.

The test ends being:

@RunWith(XTestRunner.class)
public class SplashActivityTest {

private SplashActivity splashActivity;

@Before
public void setUp() throws Exception {
splashActivity = new SplashActivity();
splashActivity.onCreate(null);
}

@Test
public void shouldHaveLoadingLogo() throws Exception {
ImageView logo = (ImageView) splashActivity.findViewById(R.id.splash_logo);
ShadowImageView shadowLogo = Robolectric.shadowOf(logo);
assertThat(shadowLogo.getResourceId(), equalTo(R.drawable.loading_logo));
}
}



The constructor is used to point Robolectric to our app project's AndroidManifest and res folder. Nothing hard there.

The magic comes in the overriden method createApplication(). The parent class use it to set the application context to Robolectric.java class in this method:

public void setupApplicationState(String projectRoot, String resourceDir) {
ResourceLoader resourceLoader = createResourceLoader(projectRoot, resourceDir);

Robolectric.bindDefaultShadowClasses();
Robolectric.resetStaticState();
Robolectric.application = ShadowApplication.bind(createApplication(), resourceLoader);
}



What do we need the application for?
Because it's used in GuiceActivity. If you check the onCreate() method, it does this:

@Override
protected void onCreate(Bundle savedInstanceState) {
final Injector injector = getInjector();
scope = injector.getInstance(ContextScope.class);
scope.enter(this);
injector.injectMembers(this);
super.onCreate(savedInstanceState);
}


getInjector()? Where's does it came from?

public Injector getInjector() {
return ((GuiceApplication) getApplication()).getInjector();
}


Conclusion: Every injection with Roboguice uses GuiceApplication.
Robolectric looks like a very powerful test fw. We will definitely use it for this new project we are working on.

Next step: ConnectivityManager Shadow!

Wednesday, November 17, 2010

TDD skeleton for Android

During this days at work my task was to research about adding tests to an Android application. The truth is that right now we aren't doing tests at all. In this entry I will try to comment on every framework I have been looking into. Let's start!

My first step was getting one of our applications and try adding black box tests. My first stop is robotium.

Robotium is a test framework created to make it easy to write powerful and robust automatic black-box test cases for Android applications. With the support of Robotium, test case developers can write function, system and acceptance test scenarios, spanning multiple Android activities.

Robotium has full support for Activities, Dialogs, Toasts, Menus and Context Menus.


Robotium is founded by the same company that created the maven-android-plugin that we have been using for a long time.

This framework looks great for blackbox testing but I didn't go too deep with it. I just made a test to browse around the app and check that the app shows the screen correctly. I had an issue with a SplashScreen but the feedback was great. I am really pleased with that.

When I reached this point my thought was: "Ok, now I can add blackbox test, but I also need unit tests!"
I try adding simple unit tests to the app but I failed. Classes were too dependent and there was lot's of logic inside the Activities. So I leave the real project away for a while and create a new one to start from the scratch with a new Architecture approach.

I present my last application: ioc_app. The ultimate app to turn a String to uppercase.


Link to the source code.

This project has two modules
a) ioc_app. The android application.
b) ioc_test. The test application.

Let me introduce some of the new stuff I added to this project:

1) Presenter first
I implemented this pattern based on the paper hosted in the link above. It's quite clear.

2) Proguard
When packaging an apk, all classes of all libraries used by the program will be included, this makes the apk very huge, even exceeds the capacity of dex. ProGuard can strip unused classes and methods, make it as small as possible.


I am missing adding proguard in an specific profile. It takes some time to compile and I don't want it to run unless I am building a release. Manfred, a committer in the maven-android-plugin project, told me he already did that and he uploaded to a sample project. I need to see that.

Manfred also mentioned he was trying to add obfuscation but he couldn't do it yet. Right now it's not my first priority but it's a nice to have feature.

3) Roboguice
Just to put it in a sentence: It's Google Guice for Android. I love the fact that from now on instead of writing:

mButton = (Button) findViewById(R.id.submit);


I will write:

@InjectView(R.id.submit)
private Button mButton;


Unfortunately Guice doesn't provide a mvn repo, so to use roboguice you will need to install guice-2.0-no_aop.jar in your maven repo.

4) Android-mock
I have some issues with this one. Running tests with mocks in Eclipse i'ts a PITA. Once again I got an excellent feedback but I preferred to go for the mvn approach.

Android-mock needs two jars to work. One for compile time and another for runtime. Right now it just work from mvn. I couldn't make it work from eclipse even though I have the m2eclipse-android-integration.

What's next?
* I am willing to read more about TDD. I have now everything configured to start doing it.
* I need to setup a Hudson to take care of the CI.
* I would like to start using IntelliJ IDEA but I couldn't manage to make my project run with it. If you did it, please let me know.

I'm hoping you give me some feedback about the skeleton and how to improve it!

Other blogs with useful info:
- http://dtmilano.blogspot.com/2008/03/test-driven-development-and-gui-testing.html
- http://www.rosscode.com/blog/index.php
- http://simpleprogrammer.com/

Sunday, November 14, 2010

Android Tip: TextSwitcher and ImageSwitcher

Quick android tip.

If you are using TextView or ImageView in your view and you are changing it's content when the user interacts, you can try using TextSwitcher and ImageSwitcher.

They work in a very similar way. The steps to use them are the following:

* Get the view using findViewById() or construct in your code like any normal android view.
* Set a factory using switcher.setFactory().
* Set an in animation using switcher.setInAnimation().
* Set an in animation using switcher.setOutAnimation().

So, if your code looks something like this:


private TextView mTextView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = (TextView) findViewById(R.id.your_textview);
...
}


and you are using mTextView.setText(something);

replace your onCreate's code with this:


Animation in = AnimationUtils.loadAnimation(this,
android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this,
android.R.anim.fade_out);

mTextSwitcher = (TextSwitcher) findViewById(R.id.your_textview);
mTextSwitcher.setFactory(new ViewFactory() {

@Override
public View makeView() {
TextView t = new TextView(YourActivity.this);
t.setGravity(Gravity.CENTER);
return t;
}
});

mTextSwitcher.setInAnimation(in);
mTextSwitcher.setOutAnimation(out);


That's it. You get some cool animations for free.

Thursday, November 11, 2010

Nuevos dispositivos Android en Argentina

Hace un tiempo un amigo me preguntó qué celular comprar con android acá en Argentina y me pregunté cuál me compraría yo.
Hoy en día sólo cambiaría mi nexus one por un Samsung Galaxy S. En su momento no había llegado a Argentina, entonces le recomendé el milestone. La historia termina con el muchacho comprándose un iPhone4 porque el milestone es muy grande.

Afortunadamente eso ya no va a pasar. El Samsung Galaxy S llegó a la Argentina de la mano de Personal a 2300$ con plan Black.



Jugué un poco con el celular y la pantalla se siente enorme. El nexus one tiene 3.7' y este tiene 4' pero la diferencia es abismal. La pantalla también es muy linda. La del iphone4 me gustó más, pero de los dispositivos con android que tuve en mis manos hasta ahora, me parece el mejor. comparativa-del-samsung-galaxy-s-con-el-iphone-4.

Como desarrollador creo que lo mejor es tener un Nexus One. Todos los updates del sistema operativo llegan para ese celular. Por ejemplo, en teoría, hoy sale el OTA de android 2.3 gingerbread para el nexus.

Pero para un usuario final, hoy en día, creo que el Galaxy S es el mejor dispositivo con Android.

Al segundo me fijé en los sitios de claro y movistar para saber si también estaba disponible. Claro tiene un sitio INNAVEGABLE por lo tanto no sé si lo tienen. Por su lado, Movistar no lo tiene pero encontré esto:



Netbook con android y con pantalla touch.

Estoy a la espera del Samsung Galaxy Tab. ¿Quién lo traerá a la Argentina?

Friday, November 5, 2010

Droidcon en Londres. Día dos. (13:30pm - 18:00pm)

Última entrega del review de la droidcon.

Después de almorzar estuve viendo algún que otro stand.

Sony Ericsson LiveView
De los sponsors que estuvieron en la Droidcon, Sony Ericsson fue el más activo. En el stand mostraban sus cels, hacían sorteos y tenían LiveView para que la gente los pruebe.

El LiveView es una especie de reloj. Se usa conectado a un celular y se le manda información por medio de BlueTooth. Noten que si usa BT sólo está disponible para 2.x y futuros releases.
Todavía no está a la venta pero va a costar 40£ (80U$s).
Me imagino muchas cosas posibles con el LiveView, entre ellas un mejor manejo de notificaciones.

Perfectomobile
El stand de Vodafone también contaba con gente de perfectomobile.
Básicamente el servicio que ofrecen es poder testear tu aplicación en muchos devices.

Más de una vez llegan comentarios o reviews en el market que dicen: "En el dispositivo x no anda el feature y". Antes eran pocos los celulares con Android y en la empresa teníamos los suficientes para probar, pero ahora ya son demasiados. Me ha pasado que algunos ni los conozco :(

El servicio parece interesante pero por ahora no se puede debuggear en el aparato. Creo que es un feature clave.

Turn good ideas in to great apps
Charla de Reto Meier. Reto dio una charla muy parecida a la que está en youtube.
Saqué en limpio esto:

Los usuarios mienten, y no siguen las instrucciones, usen analytics.
No recomendó ningún sistema en especial.

Por mi parte, ahora estoy usando Flurry pero la información de los Force Closes es muy pobre. Para eso estoy usando Acra.

Android beyond the phone; Tablets, eReaders, and more
Al Sutton dio una interesante charla mencionando los distintos dispositivos con android.
Mostraron la Dell Streak. En un principio pensaba que todo dispositivo con resolución mayor a la de un celular común iba a ser hdpi pero para mi sorpresa no es así. En el caso de la Dell Streak es mdpi.

Lamentablemente no tengo una tablet y por ahora la única solución es el emulador que provee Samsung en su página. La verdad es que en mi máquina anda lento y no me entra el dispositivo en portrait, pero algo es algo.

Interface design for Android tablets
Charla a cargo de Greg Taylor de TigerSpike. Lamentablemente a Greg le tocó la "sala" principal donde no se escuchaba nada. Greg mencionó que la UX en una tablet debería ser distinta a la de un celular y mostró un video de un mock de una posible UX. Lamentablemente no lo puede subir a internet así que no lo puedo compartir :(

Thanks & Beers
La gente de adMob se puso con cervezas y vinos para disfrutar el cierre de la conferencia.
En el cierre hablé con dos españoles, Cristobal Viedma y @androides. Parece que los chicos están interesados en armar una Droidcon en Barcelona. Enhorabuena, tíos! :)
Espero poder estar allí cuando la hagan. Suerte con eso!

Conclusión
Cada vez hay más gente desarrollando Android.
Cada vez hay más dispositivos.
Cada vez hay más markets.

En muchas charlas se dijo que tenemos que hacer nuestra aplicación tablet-compatible pero la realidad es que debería cambiar la UX. ¿Vamos a tener que hacer una única aplicación para distintos dispositivos o vamos a usar a usar Android Libraries para compartir el core entre dos aplicaciones distintas?

Dentro de poco voy a tener que migrar una aplicación que estoy haciendo a tablet, así que ahí veré qué conviene. Google mencionó que Gingerbread solucionaría algunas de estos inconvenientes. Esperemos.


Thursday, November 4, 2010

Droidcon en Londres. Día dos. (9:00am - 13:30pm)



Por suerte el día dos fue mucho más organizado. Desde el hotel había elegido a qué charlas tenía ganas de ir así que tenía todo anotado en la app de android de la conf. Schedule aquí.

Driving Downloads via Intents
La charla la dio Sean Owen, autor de la librería zxing usada en la aplicación Barcode Scanner. Creería que toda persona con Android tiene instalada esta aplicación.

Sean explicó cómo usar los intents para proveer una librería al resto de las aplicaciones. Gracias a la arquitectura de Intents que tiene android una aplicación puede ofrecer una api para que el resto la use. En el caso de Barcode Scanner, la aplicación ofrece un intent para que nuestra aplicación pueda capturar códigos de QR. ¿Qué genera esto? Que Barcode Scanner tenga muchas más descargas.

Se mostró un código interesante para resolver las dependencias de otras aplicaciones mandando al usuario al market para descargarla. Link al código.

Sean concluyó que el hecho de que Barcode Scanner sea usada tanto por otras aplicaciones logra que nadie la borre y que genere muchas más descargas. El dev debería pensar qué en su app es reutilizable por otras aplicaciones y publicar su API en lugares como openintents.

Excellence in the Android user Experience
Romain Nurik fue el orador de esta charla. Romain es un google developer advocate para la parte de UI y UX. Sus slides aquí. Algunos puntos interesantes de la charla:
  • La UX del usuario no empieza en la primera pantalla, empieza en le primer review que ven, en la pantalla del market, en el ícono de la app.
  • El usuario no se va a poner a leer documentación para usar la app. La app tiene que ser simple e intuitiva.
  • Testear con usuarios reales y ver cómo interactúan con la aplicación.
  • Hacer betas para conocer la opinión del usuario.
He vivido el último punto con Swiftkey. Desde la primera versión del teclado se armó una lista de correo donde distintos usuarios fueron probando la app y pidiendo features. El día que salió en el market ese leal grupo de usuarios fue y descargó la app, llevándola a featured en poco tiempo.

Romain también tiene una página interesante con herramientas que está haciendo.

Android Reuse Models
Nuevamente Mark Murphy con otra charla interesante.
Mark explica que existen formas de agregar dependencias por medio de jars, src code, api por intent en android pero que existe un gran problema. ¿Qué pasa cuando necesitamos usar resources?

Mostró código del ejemplo que tiene subido a su repo de github.
Colormixer es una activity para que el usuario pueda elegir un color. Tiene como dependencia cwac-parcel para el correcto manejo de dependencias.

Este es un problema que estamos teniendo en el trabajo. Implementamos código para hacer action bars de manera fácil, pero venimos copiando el src de proyecto en proyecto. Estaría bueno utilizar este formado de librería y que encima lo pueda poner como dependencia en mi pom.xml

Me comuniqué con la gente de maven-android-plugin y lo hablé en un post en su lista de correo. Ya existe el issue y Hugo le puso prioridad alta. Plz entren y pónganle una estrella :)

Android and CouchDB
Tenía ganas de que esta sea una charla increíble la cual me de el puntapie inicial para empezar a usar CouchDB en Android pero no lo logró.

Aaron Miller explicó que hoy en día CouchDB funciona como un android service. Si tu aplicación necesita usar couchDB el usuario tiene que bajar CouchDB. Sé que existen formas de llevar al usuario al market para descargar pero sólo las usaría para funcionalidades extra no para el core de mi app. Cuando le preguntaron si había forma de embeber en la app dijo que todavía no está hecho y que si se hace como está hoy son como 8MB. También tuvo la gentileza de avisar que no es su prioridad.

Mi conclusión:
Todo muy lindo, pero si Google no permite instalar apps como dependencias al instalar mi propia app CouchDB va a mantenerse sentado en el sillón.

Después de esta charla se lanzó el almuerzo.
Mañana escribiré algo de las charlas de la tarde.

Wednesday, November 3, 2010

Droidcon en Londres. Día uno



Bueno, estoy de vuelta en casa después de una semana en Londres.
Tuve la suerte de participar en la Droidcon así que voy a hacer una pequeña reseña de las cosas que vi y me llamaron la atención.

Día 1:
El primer día fue en formato barcamp. Distintos participantes hicieron una fila y la gente presente votaba qué charlas se daban. La organización no fue la mejor. Acá está el schedule del día:





Algunos puntos interesantes de las charlas que vi:

No usar intent.action.BOOT_COMPLETED a menos que sea REALMENTE necesario.
Android permite escuchar distintos eventos del sistema. Uno de ellos es el BOOT_COMPLETED. Algunos usos:

  • Settear alarmas (las alarmas se pierden cuando el cel se reinicia)
  • Iniciar un servicio
  • Iniciar o schedulear descargas detenidas al reiniciar el teléfono
¿Cuál es el problema?
Si, por ejemplo, necesitamos schedulear descargas de nuestra aplicación y esas descargas no existen, vamos a usar tiempo de inicio del celular en verificar si hay algo que hacer o no.

¿Solución?
Settear el Receiver off por defecto y habilitarlo cuando es necesario.

La presentación fue dada por @ErikHellman de SonyEricsson. A la espera de los slides.

Google Bootcamp 1
Primera charla de google.
Por más que muchos pegaron con preguntas sobre el futuro de Android la respuesta fue siempre la misma: "No podemos responder nada de eso".

Pregunté sobre una pregunta que vi en stackoverflow sobre animaciones en ListView.

Me respondió Roman. Comentó que las ListView utilizan vistas normales, y que era cuestión de obtener la View y aplicarle una animación. (Más tarde lo busqué y pude hacer un código funcional con él. Lo organizaré y lo subiré)

Continuous Integration con maven y hudson
La charla la dio el autor de maven-android-plugin. Los slides están acá.

En la parte de Q&A le comenté que lo habíamos probado en el trabajo pero que teníamos el problema de que nuestro hudson corría en un server sin X.
Matthias Käppler(@twoofour) mencionó que la nueva versión del plugin de android para hudson ya tiene eso incorporado. Será cuestión de probarlo :)

Mercados alternativos
Realmente estoy sorprendido de la cantidad de markets nuevos que hay.
Me enteré que ya existe mercado de Orange y de Vodaphone. Da la sensación que cada telco va a tener su propio market. Creo que es una buena noticia porque por ahora en el AndroidMarket sólo se puede utilizar cc y mucha gente no tiene. El hecho de que las telcos tengan market asegura que clientes puedan comprar la aplicación y que se les facture en la cuenta mensual. Dolor de cabeza para el desarrollador, pero es una opción más.

MetaMarket model
Charla por Mark Murphy (Commonsware). Para los que no lo conocen Mark es una persona MUY activa en la comunidad android. Es el único con gold badge en android en stackoverflow.

Mark plantea que el android market está bueno, pero que le faltan cosas. Ayudado por el auditorio se armó una lista de cosas que molestan tanto al desarrollador como al usuario. Entre ellas:
  • No se puede responder a los comentarios
  • No hay suficiente info de la aplicación screenshots/descripción/video
  • Las búsquedas no funcionan bien
  • No hay analytics
  • Falta de mejores detalles de la puntuación
Mark mencionó que estaría bueno que la información del market sea más pública y que la comunidad tiene que encontrar una mejor manera de manejar esto. Mencionó que el: "Google, fixeá esto" no siempre funciona :)
Habían quedado en armar una lista de correo para hacer algo con esto, pero por ahora no tengo noticias.

App Circus
En el viaje tuve la posibilidad de conocer a la gente con la cual trabajé en SwiftKey.
Ben Medlock, uno de los fundadores de TouchType, presentó Swiftkey en la App Circus.

Swiftkey salió primera y Ben se ganó una "camisa" de Fórmula 1 autografiada por Lewis Hamilton :)

El día cerró con una Hackathon en la cuál aproveché y hice el código de la animación del listado que mencioné anteriormente. Un placer poder codear y tener googlers para sacarse las dudas.

Próximamente análisis del día dos.

Friday, October 8, 2010

Abierta la registración para la DevFest 2010 Argentina


Me acaba de llegar la invitación para la devfest2010arg.

¡El 1 y 2 de Noviembre celebramos el DevFest 2010 en Argentina!
El Google DevFest es un evento que se organiza expresamente para la comunidad de desarrolladores de nuestro país.

Es una oportunidad para aprender acerca de los productos para desarrolladores de Google y conocer a los ingenieros que trabajan en ellos.

En el evento vamos a hablar sobre tecnologías móviles y web: Android, HTML5, Chrome, App Engine, Google Web Toolkit y más. La inscripción es
gratuita y está abierta para todos los programadores. Al evento asistirán ingenieros de Google de todo el mundo y por lo tanto algunas de las charlas
serán en Inglés. Para obtener información sobre las charlas podés consultar la agenda.


Vacantes disponibles hasta el 23 de Octubre o hasta agotar capacidad del lugar.


Link

Wednesday, October 6, 2010

PayPal en el Android Market?



Después de la llegada de Android market a Argentina y a un par de países más hay un nuevo rumor dando vueltas:
Online payment system por medio de PayPal.

Todo indica que se confirmará el 26 de Oct. durante la PayPal's developer conference en San Francisco.

Otro boost de posibles compradores del market :)

¿Qué estás esperando para ponerte a desarrollar?

Via androidcentral

Tuesday, October 5, 2010

Ya se pueden comprar apps en el market!




Hoy a la mañana entré al market y ya veo la solapa de "Top Paid".
Ya que estamos aproveché para comprar SwiftKey.

Al darle click al buy aparece un TOS:



Aceptar y luego derecho al detalle de google checkout:




Listo!
Acabo de comprar mi primera aplicación en el market :)

Thursday, September 30, 2010

AM/PM Tech: Desarrollo Mobile



Hoy me invitaron a una sesión de Q&A en palermo Valley.

El próximo jueves 30 de septiembre a las 19:30 hs en AreaTres vamos a realizar el primer AMPM Tech. Este ciclo estará orientado a todos aquellos interesados en las nuevas tecnologías y su relación con los negocios.


Voy a estar respondiendo las preguntas de android.

Los espero!

PD: Link

Android Market en Argentina. Confirmado!


Ahora sí.
Confirmado por google.


Support for paid application sales is now expanded to developers in 29 countries, with today’s additions of Argentina, Australia, Belgium, Brazil, Canada, Denmark, Finland, Hong Kong, Ireland, Israel, Mexico, New Zealand, Norway, Portugal, Russia, Singapore, South Korea, Sweden, Switzerland and Taiwan.


También como desarrollador ya puedo subir aplicaciones pagas.
A subir apps :)

Tuesday, September 28, 2010

Android market en Argentina?

Hoy me encontré con un mensajes por twitter de @flag con el siguiente link.

So far, the startup has identified 13 ‘new’ countries: Argentina, Belgium, Brazil, Finland, Hong Kong, Israel, Mexico, Poland, Romania, Russia, Slovakia, Singapore and South Africa. Other reports suggest Sweden and Hungary are two other countries that are starting to see paid apps support. Note that we haven’t yet confirmed this is actually the case for these countries, but Distimo’s tracking system was built to pick up things like this.


Todo indica que se viene el android market a la Argentina!

Según nightshadex101 en el siguiente link:

Esto es desde hoy, lo acabo de probar sacando el market access (dejando el sim.numeric en 72234, que es el valor para Personal).



A la espera de que se confirme la noticia!

Thursday, September 9, 2010

Confirmada la Google DevFest 2010!



Después de un tiempo se confirmó la Google DevFest en Buenos Aires, Argentina!
Se hará el 2 de Noviembre en Buenos Aires.

Por ahora no sé quién dará las charlas pero lamentablemente Reto Meier no viene :(