Geek & Roll - Blog Archive » Programando para la BlackBerry – Everlasting Flame II

Programando para la BlackBerry – Everlasting Flame II

Cesar December 30th, 2008 Uncategorized 9 comentarios

Ver primera y segunda parte.

Everlasting Flame icon

Continuamos con el desarrollo de esta aplicación. Ya en la parte dos vimos cómo programar la funcionalidad básica: monitorear el tiempo de las llamadas y reaccionar de acuerdo a los límites establecidos (denominados soft y hard limit). Ahora sigue el turno de guardar a la memoria algunas de las opciones establecidas por el usuario y crear una interfaz gráfica para la configuración.

Como vimos, Everlasting Flame es una aplicación con la que el usuario no interactúa directamente y es por esto que no contiene una interfaz gráfica. La aplicación se ejecuta automáticamente cuando el teléfono inicia, de tal modo que al marcar un número comienza a contar el tiempo. Sin embargo es conveniente tener una interfaz de configuración donde podamos establecer los límites, así como también habilitar y deshabilitar el monitoreo de llamadas (por si queremos hacer una llamada más larga de lo normal sin que se corte).

Para este propósito se crea lo que se llama un punto de entrada alternativo, que como su nombre lo indica, servirá como punto de entrada a la aplicación ejecutando una serie de pasos distintos a los “normales”. En nuestro caso el punto de entrada normal es el que no tiene interfaz gráfica y el alternativo es iniciar la interfaz gráfica para configurar la aplicación. Lo primero es configurar el proyecto como aplicación del sistema (es decir, que no muestra interfaz gráfica) y que sea auto ejecutable. Esto se hace desde Eclipse modificando las propiedades del proyecto. Después creamos un proyecto nuevo vacío y en las propiedades lo configuramos como punto de entrada alternativo al proyecto original, pasando como parámetro alguna cadena de identificación (en mi caso, “init”).

De esta manera, cuando el usuario seleccione el icono de nuestra aplicación desde la BlackBerry, nuestra aplicación recibirá como argumento la cadena “init” y eso nos servirá como señal para iniciar la interfaz gráfica. Si la aplicación es iniciada automáticamente, no recibiremos la cadena “init” e iniciaremos la aplicación como antes. Modificamos EverlastingFlame.java de esta manera:


public static void main(String[] args) {
System.out.println("On Endless main");
boolean startup = false;

for(int i=0; i < args.length; i++){
if(args[i].equals("init")){
startup = true;
}
}

if(startup){
System.out.println("Called from regular entry point, display the GUI.");
MainGUI gui = new MainGUI();
gui.enterEventDispatcher();
}else{
System.out.println("Called from alternate entry point, start the EverlastingFlame.");
EverlastingFlame ef = new EverlastingFlame();
ef.enterEventDispatcher();
}
}

Como vemos en el código, si recibimos la cadena "init" creamos una nueva instancia de MainGUI y ejecutamos su event dispatcher para que el sistema despliegue la pantalla. El código de MainGUI.java se muestra a continuación:


public class MainGUI extends UiApplication{
private MainScreen mainScreen;

public MainGUI(){
mainScreen = new EverlastingFlameScreen();
LabelField label = new LabelField("Everlasting Flame Configuration", LabelField.ELLIPSIS
| LabelField.USE_ALL_WIDTH);
mainScreen.setTitle(label);
pushScreen(mainScreen);
}
}

Esta clase extiende a UiApplication porque precisamente es una aplicación con interfaz gráfica. Contiene una MainScreen con el título de "Everlasting Flame Configuration". Por último empujamos la pantalla para que sea mostrada en el teléfono. La MainScreen es realmente una instancia de EverlastingFlameScreen, una clase que hereda de MainScreen e implementa la interfaz gráfica y los eventos que nos interesan:


public class EverlastingFlameScreen extends MainScreen{
private CheckboxField chkActive;

public EverlastingFlameScreen(){
super();

chkActive = new CheckboxField("Start monitoring service?",Options.getActive());
add(chkActive);
}

protected boolean onSavePrompt(){
if(isDirty()){
int option = Dialog.ask(Dialog.D_SAVE,
"Do you want to save changes?");
if(option == Dialog.SAVE){
onSave();
boolean chkState = chkActive.getChecked();
Options.setActive(chkState);
if(Options.getActive()){
Dialog.inform("Calls will be monitored, Mujajaja!");
}else{
Dialog.inform("Calls are no longer monitored.");
}
}else{
chkActive.setChecked(Options.getActive());
return false;
}
}
return true;
}
}

Para efectos de este ejemplo, la pantalla se compone solamente de un checkbox que sirve para habilitar o deshabilitar el servicio de monitoreo. Si este checkbox se encuentra activo, Everlasting Flame monitorea las llamadas, inyectando el tono DTMF y colgando cuando es necesario. De más está decir que si se encuentra desactivado, las llamadas transcurren normales. En el constructor se crea el checkbox en cuestión y se le pasa una cadena que será su etiqueta, así como también el estado inicial del checkbox (seleccionado o no seleccionado).

El estado inicial se obtiene de las opciones del usuario, gracias a una clase Options que nos sirve para guardar las preferencias del usuario en memoria no volátil (más de esto en la siguiente entrega de esta serie de posts). La magia ocurre en el método onSavePrompt. Este método se ejecuta cuando el sistema cree que hubo algún cambio que debe ser guardado. Nosotros sobreescribimos el método y agregamos una pequeña validación.

Cuando el sistema ejecuta onSavePrompt, verificamos el estado de la pantalla. isDirty nos indica que hubo cambios y por lo tanto hay que preguntar al usuario (por medio del método estático ask de la clase Dialog) si desea guardar. En caso de si desear guardar, verificamos si el usuario activó o desactivó el servicio y por último informamos al usuario que sus cambios han sido aplicados.

Queda solamente modificar el PhoneListener para tomar en cuenta el estado del servicio (activado o desactivado). Esto es muy sencillo utilizando la clase Options que se verá más adelante:


if(Options.getActive()){
if(callTimeSeconds == softLimit){
System.out.println("Soft limit reached");
injectDTMFTone(Phone.getActiveCall());
}else if(callTimeSeconds == hardLimit){
System.out.println("Hard limit reached, hanging up!");
injectEndCall();
}
}else{
System.out.println("Service not active");
}

Si el servicio se encuentra activo, realiza las mismas validaciones anteriores. En caso de encontrarse inactivo, simplemente no hace nada.

Lo que queda es explicar la clase Options y por supuesto agregar mayor funcionalidad a la interfaz gráfica, como por ejemplo la configuración de los límites, la acción a realizar en cada uno de ellos y cambiar el funcionamiento entre modo "naco" (funcione para todos los números) y modo "VIP" (sólo para números seleccionados).

9 Comentarios

Arturo

December 30th, 2008

Hola mi buen Cesar, como una pequeña sugerencia, no se si sea cierto o no, segun fuentes de algunas personas que conozco, el sistema como se cobra lo de los 5 minutos empieza desde que se enlaza la llamada, entonces si la persona que va a recibir la llamada se tarda en contestar esos pocos segundos se suman al tiempo de la llamada solo si el que contesta la llamada la contesta, no se si me de a entender, esto es (tiempo de los tonos de pitido mientras no contesten + tiempo de llamada si al que le llaman contesta = tiempo que cobra telcel), es por ello que seria bueno incluir en la interface gui y no se si sea mucho pedir que el usuario final de tu aplicacion determine los tiempos de colgar la llamada y el tiempo del tono DTMF para avisarle con calma a la persona que le vas a colgar y le vas a marcar de nuevo????

saludos desde Guadalajara =),

Cesar

December 31st, 2008

@Arturo de hecho los limites son configurables, falta nada mas incluirlos en la interfaz gráfica. Lo del tiempo la verdad no lo sabía, yo como lo tengo configurado es que a los 4:30 avisa con el tono DTMF y a los 4:50 cuelga la llamada, sin embargo si tu teoría es cierta y el usuario se tarda en contestar mas de 10 segundos entonces la llamada se va a pasar de los 5 minutos.

Otro plus es que si otra persona me llama (por ejemplo mi novia) puedo configurar si quiero que mi teléfono inyecte el tono DTMF cuando se supere el softlimit, de esta manera le puedo avisar a la otra persona que su llamada va a superar los 5 minutos y ayudarlo a medirse si es que tiene el plan sin fin y no cuenta con una BlackBerry (el caso de mi novia).

P.D. Me encanta Guadalajara!

Aluziner

December 31st, 2008

@Cesar muy buena esta serie de posts sobre esta aplicación que estás desarrollando, lástima que no tengo una BB para probarla, respecto a lo que dice Arturo yo también he escuchado lo mismo y de gente que trabaja en Telcel, así que quizá sea cierto.

Salu2

Arturo

January 4th, 2009

Hola de nuez, ya te empeze a hacer propaganda Cesar sobre tu software a todos mis amigos que tienen blackbery porsupuesto, cuanto crees que lo vas a vender??? para irte encargando unas cuantas licencias y otra cosa muy aparte, no se si conozcas la pagina fayerwayer donde hablan de tecnologia y como me imagino que si, me podrias decir alguna otra pagina asi de interesante para no aburrirme en mis 8 horas de descanso osease toda la noche para estar al tanto de avances tecnologicos ya que tu estas autoproclamado Geek, yo ando buscando lo mismo jejeje

gracias y saludos desde guanatos de nuevo

Cesar

January 5th, 2009

@Arturo: Gracias por la propaganda. Como dije, seguiré con el desarrollo de la aplicación conforme mi tiempo me lo permita. El costo no lo puedo saber ahora, pero te aseguro que no será muy caro, algo entre los 5 y 10 dlls por copia. Los detalles tengo que planearlos.

Con respecto a sitios, pues si hay bastantes. En la página frontal del blog ligamos a algunos como slashdot.com y arstechnica.com. De mi reader te puedo decir alt1040.com, addxorrol.blogspot.com, phoronix.com, vivalinux.com.ar, microsiervos.com, ajaxian.com y ultimamente 10puntos.info

Paco

February 18th, 2009

Bueno te tengo que dar las gracias por este aporte!! Tu programa en sí, no me es util, pero si me as ayudado muchisimo con el tema de un punto de entrada alternativo.

Muchisimas gracias!

Aunque me quedo con las ganas de como guardas los datos en memoria no volatil :(

Un saludo! y suerte!

Paco

February 18th, 2009

Uoo indagando un poco mas por la página he visto que tienes el codigo en googlecode.

Gracias maestro!! ya aprendi!!

Cesar

February 18th, 2009

@Paco así es, bajo licencia GPLv3. Si puedes comentarnos un poco más sobre la aplicación que estas haciendo, sería muy bueno.

Juan Gabriel

May 30th, 2012

Cesar yo tengo una aplicacion que se arranca al principio y escucha pines y cuando llega un determinado pin tiene que pasar al main un argumento para que se lance una pantalla que me creado y siga escuchando los pines hasta que me indique que tengo que cerrar la pantalla pero no la aplicacion que seguiria escuchando pines, no se como puedo lanzar la pantalla pasandole el argumento al main, please un poco de ayuda te lo agradeceria.

Haz un comentario:

Es necesario que dejes tu nombre y correo electrónico (no se publicarán).

Si dejas un comentario anónimo, con insultos o ajeno al tema, iremos hasta tu casa y le diremos a tu mamá la cantidad de porno que hay en tu computadora. Si, lo sabemos.