jueves, 13 de octubre de 2011

BlackBerry ApplicationIndicator class

In RIM Blackberry OS 4.6+ there is a feature - ability to show notification icon in statusbar. Integrated application use it to give quick and informative information for user: Dealler - missed calls, Messages - unread messages etc.



Possible use of notification icon:
  • missed events
  • RSS updates
  • object status (ex. weather/app activity/gps signal strength)
  • other
To add/modify/remove notification icon we can use ApplicationIndicator class:
Represents an application indicator that consists of an icon and optional numeric value.
The icon is placed in indicators area along with others such as new mail counter, calendar reminders, missed calls counter, security status and others.
  • Application can register only one indicator and has to register it every time the phone starts.
  • All indicators are cleared upon phone restart.
  • Indicators may be not visible if there will be no space on statusbar
  • Indicator dimensions depend on current theme and phone screen size.
  • The icon size varies from 10x10 up to 24x24.
  • If indicator is initialized with a big icon then an exception is thrown.
  • Indicator can have optional numeric value that usually serves as a counter.
  • The value can be negative, 0 or positive.
  • If indicator is used as a counter it's better to hide it when its value is equal to 0.
  • If indicator value is too big, it will display '99+' or '999+'

Add notification icon

For this we should create instance of ApplicationIcon:
Application icon class is used in conjunction with application indicator and application messages.
It incapsulates image and its painting properties.
EncodedImage mImage = EncodedImage.getEncodedImageResource("indicator_icon.png");
ApplicationIcon mIcon = new ApplicationIcon(mImage);
Then we should register ApplicationIndicator with ApplicationIndicatorRegistry:
ApplicationIndicatorRegistry.register(icon, iconOnly, visible)
icon - an icon to be displayed in the indicators area
iconOnly - specifies if indicator should have icon representation only and no value
visible - specifies whether indicator has to be visible initially
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry.getInstance();
ApplicationIndicator indicator = reg.register(mIcon, false, true);

Modify indicator icon and value

To modify icon, use ApplicationIndicator.setIcon method:
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry.getInstance();
ApplicationIndicator appIndicator = reg.getApplicationIndicator();
appIndicator.setIcon(icon);
To modify number value, use ApplicationIndicator.setValue method:
ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry.getInstance();
ApplicationIndicator appIndicator = reg.getApplicationIndicator();
appIndicator.setValue(value);
  • If very big value is provided then indicator will display '99+' or '999+'.
To hide or show indicator, use ApplicationIndicator.setVisible

Unregister ApplicationIndicator

Most likely you don't want your app indicator to stay in statusbar, it's better to ApplicationIndicatorRegistry.unregister() it on app close.

Sample application

Icons:









Code:
import net.rim.blackberry.api.messagelist.ApplicationIcon;
import net.rim.blackberry.api.messagelist.ApplicationIndicator;
import net.rim.blackberry.api.messagelist.ApplicationIndicatorRegistry;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.container.MainScreen;

class Scr extends MainScreen {
    EncodedImage mImageGreen = EncodedImage
      .getEncodedImageResource("bb_icon_green.png");
    ApplicationIcon mIconGreen = new ApplicationIcon(mImageGreen);
    EncodedImage mImageRed = EncodedImage
      .getEncodedImageResource("bb_icon_red.png");
    ApplicationIcon mIconRed = new ApplicationIcon(mImageRed);

    ApplicationIcon mIcon = mIconGreen;

    public Scr() {
     add(new LabelField("Use menu to:"));
     add(new LabelField("Register indicator"));
     add(new LabelField("Increment value"));
     add(new LabelField("Decrement value"));
     add(new LabelField("Switch icon"));
     add(new LabelField("Unregister indicator"));
    }

    MenuItem menuRegister = new MenuItem("register", 0, 0) {
     public void run() {
      registerIndicator();
     };
    };
    protected int mValue = 0;
    MenuItem menuIncrement = new MenuItem("increment", 0, 0) {
     public void run() {
      mValue++;
      updateValue(mValue);
     };
    };
    MenuItem menuDecrement = new MenuItem("decrement", 0, 0) {
     public void run() {
      mValue--;
      updateValue(mValue);
     };
    };
    MenuItem menuSwitchIcon = new MenuItem("icon", 0, 0) {
     public void run() {
      mIcon = (mIcon == mIconGreen) ? mIconRed : mIconGreen;
      updateIcon(mIcon);
     };
    };
    MenuItem menuUnregister = new MenuItem("unregister", 0, 0) {
     public void run() {
      unregisterIndicator();
     };
    };

    protected void makeMenu(Menu menu, int instance) {
     super.makeMenu(menu, instance);
     menu.add(menuRegister);
     menu.add(menuIncrement);
     menu.add(menuDecrement);
     menu.add(menuSwitchIcon);
     menu.add(menuUnregister);
    }

    private void registerIndicator() {
     try {
      ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
        .getInstance();
      ApplicationIndicator indicator = 
        reg.register(mIcon, false, true);
     } catch (Exception e) {
     }
    }

    private void unregisterIndicator() {
     try {
      ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
        .getInstance();
      reg.unregister();
     } catch (Exception e) {
     }
    }

    void updateValue(int value) {
     try {
      ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
        .getInstance();
      ApplicationIndicator appIndicator = 
        reg.getApplicationIndicator();
      appIndicator.setValue(value);
     } catch (Exception e) {
     }
    }

    void updateIcon(ApplicationIcon icon) {
     try {
      ApplicationIndicatorRegistry reg = ApplicationIndicatorRegistry
        .getInstance();
      ApplicationIndicator appIndicator = 
        reg.getApplicationIndicator();
      appIndicator.setIcon(icon);
     } catch (Exception e) {
     }
    }
}


miércoles, 12 de octubre de 2011

Dart : Structured web programming

Hace par de días Google anunció su rumoreado lenguaje de programación del cual les había informado en eliax, y lo ha bautizado Dart (como "Dardo"), y he estado estudiándolo y hoy les doy mis primeras breves impresiones.

Noten antes de continuar que Dart está en una etapa muy temprana de su desarrollo. Google lo considera un "Technology Preview" (un avance sobre lo que será), y no una versión final, destacando explícitamente que muchas cosas podría cambiar de aquí a la primera versión oficial.

Lo primero a destacar de Dart es la razón de su existencia, las razones son potencialmente las siguientes:

1. Javascript, el lenguaje por defecto para programar aplicaciones web en navegadores está fuera de control. Inició como algo sencillo, pero se ha vuelto toda una bestia, y al no tener estructura promueve demasiado la producción de "código spagetti" en donde al programa le falta estructura y en donde todo se vuelve difícil de mantener, en particular en proyectos grandes (algo que he vivido en carne propia).

2. Con HTML5, es complicado y tedioso cambiar contextos con distintos lenguajes de programación y declarativos, siendo la norma el combinar en un solo código fuente a Javascript, HTML, CSS, y algún otro lenguaje de servidor (como puede ser PHP, JSP, ASP, etc). Esto es algo que los que programamos con frecuencia aplicaciones web nos enfrentamos constantemente.

3. Siguiendo el punto anterior, otro problema es que la aplicación web típica por lo general se divide en dos lenguajes de programación distintos. Uno para el cliente (Javascript) que se ejecuta localmente en el navegador, y otro para servidores (PHP, JSP, ASP, etc). En vez de uno poder programar todo en un solo lenguaje.

4. Lenguajes como Javascript y PHP no fueron diseñados para escalar masivamente de forma horizontal.

Dart promete resolver todo esto, con un lenguaje super sencillo y que resultará familiar para toda persona que tenga al menos un conocimiento básico de Java, C#, o similares.

Dart parece un cruce entre Java y Javascript, por un lado soportando las estructuras de Java (Classes, Interfaces), pero por otro permitiendo opcionalmente la declaración de variables sin tipos explícitos (de forma similar a Javascript, Visual Basic o ColdFusion).

Dart además fue pensado para escalar masivamente, de modo que aplicaciones creadas en Dart para ambientes de servidores podrían por ejemplo comportarse como las de Google en sus inmensas granjas de servidores, tomando ventaja de patrones de alta escalabilidad.

Por ejemplo, algo que noté curioso sobre Dart es que intencionalmente es single-threaded (es decir, soporta un solo hilo de ejecución), lo que a primera vista aparenta una gran restricción, pero al leer la especificación técnica se hace evidente que reemplazaron el concepto de multi-threading por el concepto de Isolates (popularizado por el lenguaje Erlang).

Isolates en esencia es bastante similar a programar Processes en C bajo ambientes UNIX. Es decir, es como hacer un fork (o bifurcación de código) de un nuevo programa, en esencia separando el Isolate de tu programa por completo.

Esto tiene como gran beneficio que ahora tanto tu programa como los que desprendas de él en forma de Isolates se pueden paralizar de forma sencilla y altamente escalable.

Obviamente es necesario poder uno comunicarse entre el programa principal y los Isolates desprendidos, y para eso se adoptó un sistema de mensajería por queue.

Según Google, estas facilidades de Dart permitirán crear desde pequeños programas por un solo desarrollador, hasta complejos mega-sistemas con grandes equipos de desarrolladores, programando desde aplicaciones móviles hasta aplicaciones en la nube para millones de usuarios, todas con un solo lenguaje y entorno de ejecución.

Por si no lo han notado, Dart entonces apunta no solo a ser un reemplazo de Javascript en navegadores web al largo plazo, sino que además un reemplazo de Java, .Net, Metro, Objective-C, PHP y todo otro lenguaje que se puedan imaginar.

Esa es una meta bastante ambiciosa, pero creo que dado que Dart es apoyado por Google (lo que significa que no tardaremos en ver entornos de ejecución nativos de Dart en Google Chrome y Android OS), y que Dart intrínsecamente es un lenguaje sencillo de rápido aprendizaje y con una sintaxis que resultará familiar a muchos, que tiene buenas posibilidades de tener éxito.

Y hablando de entornos de ejecución, Dart funciona de dos maneras: La primera y más obvia es en una máquina virtual Dart, similar a como ejecuta Java, lo que podemos llamar la forma "nativa" de ejecutar aplicaciones Dart.

La otra manera es con un convertidor que convierte programas Dart a Javascript, lo que permitiría a desarrolladores ir trabajando con Dart mientras migran de Javascript y esperan que los proveedores de navegadores web adopten el lenguaje.

Por el momento el convertidor funciona con versiones recientes de Chrome, Firefox y Safari (todavía no con Internet Explorer). Lo ideal obviamente sería que Mozilla, Apple y Microsoft implementaran la máquina virtual de Dart en sus navegadores, pero habrá que esperar a ver si estas instituciones y empresas no se sienten amenazadas por Dart y están dispuestas a adoptarlo.

Una buena noticia es que Google ha hecho a Dart 100% Open Source, con la esperanza sin duda de que Dart se convierta en un estándar por-defecto, y que quizás sea adoptado por competidores bajo la promesa que al igual que HTML5, la industria sería quien defina su futuro (aunque bajo la tutela de Google, muy posiblemente).

Personalmente, este es el primer lenguaje de programación que verdaderamente me emociona desde los días del inicio de Java, pues con su simpleza se presta mucho a uno ser muy productivo rápidamente.

En nota relacionada, les traigo lo que para muchos quizás sea una primicia relacionada a Dart: Todos los rumores apuntan a que Google está desarrollando también un IDE (un entorno de programación visual integrado) que se ejecutará como un servicio "en la nube" al cual internamente llaman "Brightly" ("Brillante").

La idea de Brightly sería una que he mencionado varias veces en muchas de mis charlas en vivo: El desarrollo de un IDE que funciona al 100% dentro de tu navegador Web, con todos tus archivos fuentes archivados en la nube, lo que significa que podrás trabajar desde cualquier lugar, a cualquier hora, en cualquier máquina que tenga un navegador web moderno, y quizás con un simple clic arrancar la aplicación en un ambiente de prueba o producción (como bien podría ser el Google App Engine).

Una nota final que quiero agregar es que no se apresuren a declarar la muerte prematura de Javascript. Javascript estará con nosotros por mucho tiempo más, en particular dada las millones de páginas web que dependen de ese lenguaje en la actualidad, y del hecho que Dart aun está en etapa de desarrollo, por lo que aun si se convierte en todo un éxito su impacto no se empezará a sentir por al menos 2 años más.

Sin embargo, si tienen un tiempo libre, no estaría mal que le dieran una repasadita a los documentos técnicos de Dart, e incluso que prueben crear un par de programas en el lenguaje, o hasta sugerir cambios a Google en esta etapa abierta para comentarios. Este bien podría ser parte del futuro de la web...

Dart : Structured web programming

Bluestacks :: App Player for Windows :: Run apps fast on your PC or tablet

This application lets you run Android applications in your PC (Mac soon)

Check this video on Youtube: http://youtu.be/Nus9-Tu_J9k

Bluestacks :: App Player for Windows :: Run apps fast on your PC or tablet

miércoles, 5 de octubre de 2011

Utilizing the HTML5 File API to choose, upload, preview and see progress for multiple files

Excelente código para subir archivos usando AJAX. Lo nuevo es que permite el famoso "drag & drop" (al mejor estilo Gmail) para arrastrar tu archivo hasta el browser y luego subirlo.
Lo probé en Firefox y Chrome, dando excelentes resultados!

Utilizing the HTML5 File API to choose, upload, preview and see progress for multiple files - Robert's talk