programacion movil
Post on 01-Jan-2016
46 Views
Preview:
TRANSCRIPT
davidbuenov.blogspot.com/2010/05/programacion-de-moviles-por-donde.html
Programación de móviles. ¿Por dónde
empiezo? (1ª Parte)
La respuesta a esta pregunta hace un par de años era más sencilla
que en la actualidad. Por decirlo de forma muy simplificada, hace dos o tres años la
mayoría de los teléfonos eran compatible con los "Juegos Java" que todavía seguimos
viendo en la publicidad de algunas cadenas. La respuesta en esos días hubiera sido
aprende a programar Java ME (MIDP/CLDC). Porque aunque había otras posibilidades
como programar en C++ para Symbian (Sistema Operativo de los teléfonos Nokia) esta
programación era bastante más complicada.
La programación en Java ME ha sido durante varios años la vencedora indiscutible. La
programación de Midlets (programa principal de una aplicación Java ME) no es
demasiado compleja y está perfectamente preparado para el desarrollo de Juegos gracias
al conjunto de clases relacionadas con GameCanvas que permiten de forma 'sencilla'
crear un escenario TiledLayer, animaciones con Sprites, detección de colisiones, etc.
Además de esto, las comunicaciones a través de bluetooth permiten comunicar el movil
con otros móviles, con un PC o usando 3G conectarse con cualquier servidor en Internet
realizando un simple URLConnection de Java.
En la actualidad todo se ha complicado bastante. Aunque Java ME teniendo bastante
que decir durante algún tiempo por su integración con diferentes sistemas operativos,
como SymbianOS que continua siendo el más extendido. En la siguiente figura se ve
como se reparte el mercado de los móviles en la actualidad.
Estadísticas Mundiales de Sistemas Operativos de Móviles
Puede comprobarse que si queremos estar al día deberemos aprender más cosas además
de Java ME. ¿Que tal aprender a programar un iPhone?Sobre todo si miramos las
estadísticas en España.
Estadísticas en España de Sistemas Operativos de Móviles
Parece que en nuestro país el iPhone se ha hecho un buen hueco. Yo que soy poco Mac-
arra (aunque mi compañero Juan Falgueras me esté iniciando) tengo que reconocer que
la usabilidad del iPhone es muy buena a pesar de sus limitaciones como limitaciones de
bluetooth o la monotarea que en la última versión se ha solucionado. Una de las
características que pienso que lo han hecho tan popular es introducción del primer
MarketPlace(llamado AppStore) en el que hay una cantidad innumerable de
aplicaciones gratuitas o a precios muy reducidos. Aunque estos precios sean muy bajos,
rondan 1€, si una aplicación tiene un millon de descargas pues has ganado un millón de
euros. Eso ha motivado a muchos programadores y podemos encontrar un gran número
de aplicaciones en versión Lite (versión reducida gratuita) y en su versión Completa.
¿Cómo se programa un iPhone o su hermano mayor iPad? Tienes dos formas de
hacerlo. Si sabes programación Web estás de enhorabuena, por el iPhone y por la
programación de Widgets de la que hablaré más tarde. Un gran porcentaje de las
aplicaciones que se encuentran en el AppStore son en realidad aplicaciones Webs
adaptadas para las dimensiones del iPhone/iPad. La página de desarrollo de WebApps
es Safari Dev Center, en la que se tiene toda la documentación del HTML,CSS y
Javascript) soportado por el navegador Safari dentro del iPhone (HTML5).
Las Web Apps de iPhone tiene algunas limitaciones respecto al acceso a características
interesantes del teléfono como el acelerometro, la cámara, GPS brújula digital y todo lo
relacionado con telefonía. Si queremos hacer algo con eso vamos a tener que
remangarnos, comprarnos un iMac y empezar a desarrollar con el entorno de dessarrollo
Xcode y aprender Cocoa y Objective-C, que es como un C++ pero 'raro' para los que
estéis acostumbrados a Java o C++. Por ejemplo, lo que en Java o C++
sería label.setText("Hola Mundo") en Objective C es [label setText:@"Hello World"];
Aunque hay que reconocer que el entorno XCode es bastante amigable y el emulador
funciona muy bien. (Pero solo en un Mac). Si te interesa, aquí tienes un libro gratuito de
la página de Apple del lenguaje Objective C.
En el siguiente capítulo hablaremos de otras tecnologías que van a arrasar el mercado.
Los Widgets (Nokia, Vodafone 360, Bondy,...) y Android.
blog.intelligenia.com/2012/02/programacion-movil-en-android.html
Programación móvil en Android: Customizando TableLayout jueves, 16 de febrero de 2012
Publicado en Desarrollo para Móviles
En esta entrada vamos a adentrarnos a nivel técnico en un aspecto concreto del diseño
de interfaces en Android. Vamos a hablar de uno de los layouts más básicos de una
interface como es el TableLayout y de cómo darle las características propias de una
tabla.
Aunque antaño los malos hábitos hacían que las tablas fueran el elemento más usado para
crear interfaces en web y pasaran desapercibidas para el usuario, hoy en día su uso está
limitado a aspectos muy concretos para una correcta estructuración de los datos y en los que
el usuario es plenamente consciente de su existencia. Es por eso que cuando representamos
una tabla pretendemos que presente las características típicas de esta: bordes, cabecera,
letras en negrita, fondo de colores... Es en este aspecto donde el TableLayout falla porque
como bien dice la documentación de Android: "TableLayout containers do not display border
lines for their rows, columns, or cells", es decir, dicho Layout no contempla bordes y por tanto
es un simple organizador de elementos en columnas y filas. A lo largo de este post vamos a
intentar darle forma a una tabla y tratar de darle las características que deseemos.
Empecemos por el principio, si revisamos de nuevo la documentación de Android para este
tema, veremos que es un contenedor de TableRows y este es a su vez otro contenedor de
Views, es decir, podemos insertar el elemento que deseemos ya sea una imagen, texto o
incluso otra tabla (lo normal es insertar TextViews). De esta forma en número de filas vendrá
determinado por la cantidad de TableRows y el de columnas por el máximo número de Views
que haya dentro de una fila.
Bien, una vez tenemos claros todos los aspectos de TableLayout vamos a ver las posibles
soluciones que se han dado al problema planteado:
Solución 1: Esta solución es la primera que se dió en cuanto se detectó el problema y
además es la más sencilla. Consiste en dar un color de fondo al TableLayout y otro diferente a
cada celda, de esta forma creamos la falsa impresión de que la tabla tiene un borde (observar
que hay que dejar márgenes en cada celda para que esto ocurra).
Superposición del fondo de cada celda con el fondo de la tabla
El resultado de aplicar el código ( layout/main.xml) sería el siguiente:
Esta solución, aunque sencilla, no permite gran flexibilidad (por ejemplo que la cabecera y el
cuerpo tengan diferente borde) y tampoco es muy fina (se basa en una superposición).
Solución 2: No es mucho más compleja que la anterior y permite mucha más
flexibilidad. Se trata de otorgarle bordes a cada celda mediante los elementos de diseño
llamados drawables, estos elementos pueden ser imágenes o incluso xmls que definen formas,
en nuestro caso vamos a usar lo segundo. Por tanto, la forma de proceder sería sencillamente
construir un xml drawable que defina los bordes y asignárselo a todas las celdas. Si queremos
varios tipos de bordes tan solo tenemos que crear varios tipos de xmls drawables y
asignárselos a las celdas que queramos. De esta forma para cambiar el color de fondo o los
bordes de X celdas tan solo tenemos que cambiar el drawable y no todas las celdas una a una,
además nos ahorramos añadir márgenes y definir el fondo en el tableLayout. Por último, cabe
añadir que para añadir un drawable a un View hay que asignárselo en la propiedad
brackground.
Podemos ver el código de la solución
en layouts/main.xml, drawable/celda_cuerpo.xml y drawable/celda_cabecera.xml y su
resultado en la interface sería el siguiente:
Hasta aquí obtenemos los mismos resultados que la solución 1 pero de una manera más
elegante, no obstante, la incorporación de tipos de celdas y elementos drawables nos da una
potencia y flexibilidad que nada tienen que ver con la solución anterior, pudiendo:
Redondear bordes Puntear bordes Añadir Gradientes Incorporar imagenes al fondo Y hasta donde la imaginación llegue
Los transformaciones y estilos quedan supeditadas a los tipos de formas que podamos crear
con shape que no son pocas. Aunque si tenemos más ganas de probar, también podemos usar
otros elementos diferentes a shape como por ejemplo un layer-list que combina varios tipos
de drawables como shape e imagenes pudiendo crear cualquier cosa imaginable.
Veamos un ejemplo:
Y para hacer estos cambios tan solo hemos tenido que modificar los dos xml drawables que
teníamos (Ver códigos en drawables/celda_cuerpo.xml y drawables/celda_cabecera.xml )
Además de las dos soluciones expuestas anteriormente existen otras muchas que se basan en
la modificación del código de TableLayout o adaptaciones en la implementación, en cualquier
caso son mucho más tediosas y no llegan a permitir la misma flexibilidad y sencillez que la
solución 2. De hecho, con esta última y un poco de paciencia e imaginación se puede lograr
cualquier tipo de tabla:
Ha sido un placer poner un granito de arena en este magnífico blog y espero intervenir en
algún post más en el futuro. Espero también que os sirva en vuestros proyectos con Android y
no olvidéis comentarlo si lo usáis ;)
Fuente: http://stackoverflow.com/questions/2108456/how-to-create-a-table-with-borders-in-
android
leo.ugr.es/J2ME/TOOLS/index.html
Tutorial: herramientas de programación
JAVA de dispositivos móviles
Versión: 1.0, Septiembre, 2006
Autor: Manuel Gómez Olmedo Web: http://decsai.ugr.es/~mgomez, Mail: mgomez@decsai.ugr.es
(C) Dpto. de CCIA Web: http://decsai.ugr.es
Introducción
En este tutorial se inicia al alumno en el uso de la herramienta KToolbar, una de las
herramientas disponibles para la realización de aplicaciones para dispositivos móviles.
En ella, una vez escrito el código fuente, puede crearse un proyecto que permite
compilar y preparar el código para su ejecución en un emulador apropiado. De hecho, el
producto final de esta herramienta puede ser instalado, de forma directa, en el
dispositivo móvil en que vaya a emplearse. Así no tendremos que descargar nada, ni
pagar....
Índice
1. Herramientas necesarias. Instalación
2. MIDlets y MIDlet suites
3. Ejecución de MIDlets
4. Uso de KToolbar
Herramientas necesarias. Instalación
Para poder compilar y ejecutar aplicaciones para dispositivos móviles necesitamos
disponer de las siguientes herramientas:
Java 2 SDK, o bien cualquier otro entorno de desarrollo que ofrezca un compilador en linea de comandos para JAVA. Se recomienda el uso del SDK de JAVA, ya que los ejemplos vistos en clase se centrarán sobre esta herramienta. Se puede descargar de la página de SUN, en la siguiente dirección: http://java.sun.com/javase/downloads/index.jsp. Nosotros trabajeremos en el aula de prácticas con la versión 5, actualización 6, aunque ya hay disponibles versiones más recientes (actualización 8, e incluso verión 6 en modo beta).
Java 2 Micro Edition. Se trata del paquete completo de desarrollo necesario. Incluye la herramienta KToolbar, junto con el perfil MIDP. Mediante la herramienta KToolbar se puede compilar código sin necesidad de interactuar directamente con CLDC, al mismo tiempo que se dispone de un emulador de terminal telefónico. De esta forma se puede comprobar el funcionamiento de la aplicación sobre un teléfono móvil. Se puede descargar en la dirección http://java.sun.com/javame/downloads/index.jsp. La versión más reciente es la 2.5, aunque nosotros trabajaremos con la 2.2. Esta versión puede descargarse desde http://java.sun.com/products/sjwtoolkit/download-2_2.html.
CLDC 1.1. Esta herramienta sólo se necesita si se trabaja a bajo nivel, por ejemplo, para incorporar código nativo (en lenguaje C) que se quiera incorporar a la aplicación. Se trata de la versión más reciente de CLDC. El software necesario se puede encontrar en la dirección: http://www.sun.com/software/communitysource/j2me/cldc/download.xml. Para instalar convenientemente CLDC hemos de seguir los siguientes pasos (para linux):
1. Una vez descargado el archivo j2me_cldc_1_1-fcs-src-winunix.zip (se trata de los fuentes del CLDC, comunes para windows, linux y otras plataformas), procederemos a descomprimirlo. Supongamos que el directorio donde está ubicado el zip es $HOME/java. Si aquí se descomprime el archivo (mediante el comando unzip nombrearchivo ), se generará el directorio j2me_cldc, donde se extraerán los archivos integrados en el zip. Uno de los subdirectorios creados bajo j2me_cldc es build. Bajo el directorio build se pueden encontrar diversos directorios, relativos a las diferentes plataformas para las que está disponible CLDC. Mirad si se encuentra el directorio $HOME/java/j2me_cldc/bin/linux. En caso afirmativo, aquí termina el proceso de instalación. En caso contrario es preciso continuar.
2. El siguiente paso a realizar consiste en situarnos en el directorio asociado a la plataforma para la que se va a hacer la instalación. En nuestro caso cambiaremos al directorio linux (dentro del directorio build). El contenido de este directorio es un archivo Makefile, que contiene las órdenes necesarias
para instalar la versión adecuada de CLDC. Basta ejecutar, en dicho directorio, el comando make.
3. Así se genera la máquina virtual, en el directorio $HOME/java/j2me_cldc/bin/linux. La máquina virtual se denomina kvm.
Netbeans. Se trata de un entorno completo de desarrollo de aplicaciones JAVA, con módulos especiales para aplicaciones sobre dispositivos móviles. Dicha herramienta se puede descargar de la dirección: htpp://www.netbeans.org. Nosotros usaremos la versión 5, aunque hay disponibles versiones beta más recientes.
MIDlets y MIDlet suites
Las aplicaciones JAVA que se ejecutan en dispositivos que implementan MIDP se
denominan MIDlets. Un MIDlet consta de al menos una clase JAVA, que debe derivar
de la clase base abstracta javax.microedition.midlet.MIDlet. El tiempo de ejecución
de un MIDlet viene controlado por una serie de métodos definidos en dicha clase y que,
forzosamente, todas las clases derivadas deben implementar.
Un grupo de MIDlets relacionados pueden agruparse en un MIDlet suite. Todos los
MIDlets de un suite se agrupan e instalan en un dispositivo como si fuesen un único
elemento, de forma que sólo pueden desinstalarse y eliminarse en conjunto. Los
MIDlets agrupados en un suite comparten tanto recursos estáticos como dinámicos:
En tiempo de ejecución, si los dispositivos soportan ejecución concurrente, todos los MIDlets se ejecutarán en la misma máquina virtual. Por tanto, todos los MIDlets comparten las mismas instancias de todas las clases, así como los recursos cargados en la máquina virtual. Entre otras cosas, esto supone que se pueden compartir datos entre MIDlets y que las primitivas de sincronización no sólo deben usarse para proteger frente al acceso concurrente dentro de cada MIDlet, sino también el producido por otros MIDlets asociados al mismo suite.
El almacenamiento persistente es gestionado de forma globar para todos los MIDlets del suite. Por tanto, los MIDlets pueden acceder tanto a sus propios datos persistente como a los de otras clases del MIDlet.
Como ejemplo de la forma en que los MIDlets de un suite comparten recursos,
supongamos un suite que contiene una clase denominada Contador, destinada a
mantener la cuenta del número de instancias de MIDlets del suite que se ejecutan en
cada momento.
public class Contador {
// Contador del numero de instancias
private static int instancias;
public static synchronized void incrementar(){
instancias++;
}
public static synchronized void decrementar(){
instancias--;
}
public static int obtener(){
return instancias;
}
}
Una única instancia de esta clase se cargará en la máquina virtual, sin importar cuántos
MIDlets de los que integren el suite están en ejecución en la máquina virtual. Esto
significa que el mismo dato miembro estático instancias será usado por todos los
MIDlets, por lo que los métodos incrementar y decrementar afectarán al mismo
contador. En este caso es necesaria la sincronización para asegurar que las operaciones
de incremento y decremento sean realmente atómicas.
Es importante indicar que los MIDlets deben empaquetarse antes de poderse instalar en
los dispositivos de destino. Todo lo necesario de un suite debe empaquetarse en un
archivo JAR. La información del paquete debe incluirse en un archivo de manifiesto.
Esta información también estará especificada en otro archivo denominado descriptor
de aplicaciones JAVA (JAD: java application descriptor), que se mantiene separado
del archivo JAR.
Los archivos de manifiesto y JAD son archivos de texto con la siguiente estructura:
nombre_atributo: valor_atributo
El nombre del atributo y su valor están separados por dos puntos, siendo el espacio
adicional opcional. Todos los atributos que son relevantes para la instalación de
MIDlets comienzan por el prefijo "MIDlet-". Una lista completa de atributos, junto con
una breve descripción de sus valores asociados, aparece en la tabla siguiente. Los
valores en las columnas JAD y JAR indican que el atributo es obligatorio (M), opcional
(O) o ignorado (I).
Nombre de
atributo
JAR JAD Valor y significado
MIDlet-Name M M El nombre del suite integrado en el archivo JAR.
El usuario podrá ver este nombre
MIDlet-
Version
M M El número de versión del suite empaquetado en el
archivo JAR. Los número de versión tienen la
forma a.b.c, donde valores mayores indican
versiones más recientes, teniendo los números de
la izquierda mayor precedencia
MIDlet-
Vendor
M M El nombre del fabricante del suite. Se trata de
texto libre.
MIDlet-n M I Atributo que describe cada uno de los MIDlets que
integran el suite. El valor numérico n comienza en
1 y sirve para identidicar cada uno de los MIDlets
MIDlet-
Description
O O Una descripción del suite, para servir de
información a los usuarios
MIDlet-Icon O O Un icono que representa al suite durante la
instalación o configuración. Se debe tratar de una
imagen en formato png (Portable Network
Graphics)
MIDlet-Info-
URL
O O Dirección URL de un archivo que contiene
información adicional sobre el suite. El contenido
del archivo se mostrará al usuario, de forma que
éste pueda decidir si desea o no instalar dicho
suite.
MIDlet-Data-
Size
O O Mínima cantidad de espacio de almacenamiento
persistente para que el suite funcione de forma
correcta. Se trata de espacio usado por el suite
para almacenar datos de larga duración. Se
espcifica en bytes. Si no se proporciona este
atributo, se asume que el suite no precisa
almacenamiento persistente
MIDlet-Jar-
URL
I M La dirección URL del archivo JAR que contiene el
suite
MIDlet-Jar-
Size
I M El tamaño del JAR que contiene el suite, en bytes
MIDlet-
Install-Notify
I O Una dirección URL usada para indicar condiciones
de error o de éxito en la instalación del suite. Se
trata de un atributo no incluido en la
especificación MIDP, pero soportado por J2ME.
MIDlet-
Delete-
I O Mensaje a mostrar en caso de que el suite vaya a
ser borrado del dispositivo. Con este atributo
Confirm ocurre lo mismo que se indicó respecto al
anterior: se trata de un atributo no incluido en la
especificación de MIDP
MIDlet-
specific
attributes
O O Los desarrollados de MIDlets pueden proporcionar
atributos específicos
MicroEdition-
Profile
M I La versión de especificación MIDP con la que el
suite puede trabajar. Cuando aparecen varias
versiones deben separarse mediante espacios.
Las versiones especificadas en este atributo se
comparan con el valor de la propiedad
microedition.profiles para determinar la
compatibilidad del suite con la versión de MIDP
disponible
MicroEdition-
Configuration
M I La configuración J2ME precisada por el suite. El
valor de este atributo se compara con la
propiedad microedition.configuration para
determinar la compatibilidad
Se aprecia que alguna información aparece duplicada en el archivo de manifiesto del
JAR y en el archivo JAD. Veremos por qué esto es necesario. La función del archivo de
manifiesto es indicar al dispositivo el nombre y versión del suite almacenado en el JAR,
así como indicar cuáles de los archivos empaquetados se corresponden con cada uno de
los MIDlets. Para usar esta información el dispositivo debe descargar el JAR y extraer
el archivo de manifiesto. Una vez hecho esto, se pueden mostrar los valores de los
atributos MIDlet-Name, MIDlet-Version, MIDlet-Vendor. También de los atributos
opcionales MIDlet-Description y MIDlet-Icon. Estos atributos permiten al usuario
decidir sobre la descarga. No obstante, el archivo JAR podría ser muy grande, por lo
que llevaría mucho tiempo recuperarlo en situaciones de conexiones lentas, por
ejemplo. Para evitar este problema, algunos de los atributos del manifiesto, con
información extra, se duplica en el archivo JAD. Esto permite descargar inicialmente el
archivo JAD en lugar del JAR. De esta forma, se puede mostrar al usuario la
información del suite antes de haber descargado el archivo de sus clases. El archivo
JAD contendrá información contenida en el manifiesto y alguna particular. Típicamente,
los atributos que aparecen en él son:
MIDlet-Name
MIDlet-Vendor
MIDlet-Version
MIDlet-Description
MIDlet-Icon
MIDlet-Info-URL
MIDlet-Data-Size
MIDlet-Jar-Size
MIDlet-Jar-URL
El objetivo de estos atributos, como se indicó con anterioridad, es ofrecer información
sobre los MIDlets incluidos en el suite. Supongamos que desarrollamos un suite
denominado Notas que permiten al usuario acceso directo a sus notas desde un
dispositivo móvil. El suite contiene dos MIDlets: uno para ver las notas y otro para
enviar información sobre posibles errores en ellas. Para desarrollar la clase se han usado
métodos de utilidad, pertenecientes a la clase Utilidades. En definitiva, las clases
involucradas serían las siguientes (teniendo en cuenta que forman parte del paquete
desarrollo.moviles):
desarrollo.moviles.VerNotas desarrollo.moviles.ErrorNotas desarrollo.moviles.Utilidades
El manifiesto para este suite podría ser el siguiente:
MIDlet-Name: Notas
MIDlet-Vendor: Programas Pepe
MIDlet-Version: 1.0.1
MIDlet-Description: Conjunto de midlets para ver notas
MIDlet-Icon: /desarrollo/moviles/iconos/notas.png
MIDlet-Info-URL: http://www.programaspepe.com/notas/info.html
MIDlet-Data-Size: 512
MicroEdition-Profile: MIDP-1.0
MicroEdition-Configuration: CLDC
MIDlet-1:
Visualizador,/desarrollo/moviles/iconos/ver.png,desarrollo.moviles.Ver
Notas
MIDlet-2:
Errores,/desarrollo/moviles/iconos/error.png,desarrollo.moviles.ErrorN
otas
En el archivo JAR correspondiente, el archivo de manifiesto aparecería como
META.INF/MANIFEST.mf. El archivo JAR también contendría los siguientes
archivos:
/desarrollo/moviles/VerNotas.class /desarrollo/moviles/ErrorNotas.class /desarrollo/moviles/Utilidades.class /desarrollo/moviles/iconos/notas.png /desarrollo/moviles/iconos/ver.png /desarrollo/moviles/icones/error.png
Conviene hacer algunos comentarios en relación al valor de los atributos y al contenido
del archivo JAR:
El archivo JAR contiene las clases correspodientes a ambos MIDlets. Aunque la clase de utilidades se incluye no hay ninguna referencia a ella en el manifiesto.
El atributo MIDlet-Icon contiene la ruta absoluta del archivo que contiene el icono del suite.
Asociado a cada MIDlet hay un atributo que describe su nombre y le asocia un identificador. El valor del atributo incluye nombre, icono y clase asociada.
El archivo JAD asociado a este MIDlet contendrá la siguiente información:
MIDlet-Name: Notas
MIDlet-Vendor: Programas Pepe
MIDlet-Version: 1.0.1
MIDlet-Description: Conjunto de midlets para ver notas
MIDlet-Info-URL: http://www.programaspepe.com/notas/info.html
MIDlet-Data-Size: 512
MicroEdition-Jar-Size: 10132
MIDlet-Jar-URL: http://www.programaspepe.com/notas/Notas.jar
Este archivo contiene la información que la pantalla del dispositivo mostrará al usuario,
junto con la dirección URL del archivo JAR. En este caso, los atributos comunes tienen
el mismo valor tanto en el archivo de manifiesto como en el archivo JAD. Para que el
suite sea portable, es preciso que el archivo JAR esté codificado usando la codificación
iso-8859-1, ya que se precisa que todas las implementaciones de MIDP soporten esta
codificación.
En tiempo de ejecución los MIDlets pueden acceder a los archivos del JAR asociado al
suite y obtener información sobre los valores de los atributos.
Ejecución de MIDlets
Simplemente, como comentario inicial, aunque se comentará más tarde, los MIDlets
deben derivar de la clase abstracta javax.microedition.midlet.MIDlet, que contiene
métodos destinados a controlar el tiempo de ejecución de los MIDlets. Todos los
MIDlets deben tener un constructor público predeterminado (es decir, que no requiera
argumentos). La estructura básica de un MIDlet se muestra a continuación:
public class EjemploMidlet extends MIDlet{
// Constructor: opcional. Bastaría con el constructor por
// defecto
public EjemploMidlet(){
}
// Método que iniciará la ejecución del MIDlet
public void startApp() throws MIDletStateChangeException{
}
// Método que interrumpe la ejecución del MIDlet
public void pauseApp(){
}
// Método para finalización del MIDlet
public void destroyApp(boolean unconditional)
throws MIDletStateChangeException{
}
}
En todo momento, los posibles estados en que podría estar un MIDlet son:
pausa activo destruido
Inicialmente, cuando se produce la carga de un MIDlet, éste estará en estado pausa.
Cuando se produce la llamada al método startApp() se produce el paso al estado
activo. En cualquier instante, la plataforma MIDP podría poner a un MIDlet en estado
de pausa. Por ejemplo, en los teléfonos móviles esto ocurrirá cuando se detecta una
llamada entrante. Esto se realiza mediante una llamada al método pauseApp(). La
vuelta al estado activo precisa de una nueva llamada a startApp(). Cuando se precisa la
finalización de un MIDlet se usará una llamada a destroyApp(...). Al producirse esta
llamada se liberan los recursos que el MIDlet pudiera estar usando, siempre que el
argumento de este método sea true. Pero pudiera haber algunas situaciones en que este
tipo de finalización no es conveniente; por ejemplo, por haber datos que aún no se han
almacenado. En este caso, la llamada al método debería hacerse usando como
argumento false. Esto produce el lanzamiento de la excepción
MIDletStateChangeException. El código debería estar preparado para capturar la
excepción y actuar en consecuencia.
Para ilustrar el ciclo de vida un MIDlet y la forma en que se controla, a la vez que
mostrar el funcionamiento de las herramientas de generación de MIDlets, vamos a
considerar un ejemplo sencillo de MIDlet, caracterizado por:
El MIDlet se llamará EjemploMIDlet1. El constructor imprime el valor de la propiedad color (ya veremos para qué se hace esto) y muestra un mensaje indicando que el midlet está construido y el valor de la propiedad.
El método startApp() se encarga de mostrar un mensaje que permita trazar el ciclo de vida del MIDlet. A continuación se hace lo siguiente:
o Si es la primera vez que se llama al método startApp(), entonces se crea un objeto auxiliar de la clase Tarea, que permite, en una hebra aparte, ejecutar una simple cuenta. Después de crear este objeto se invoca al método start() del mismo, de forma que empieze a desarrollarse la tarea indicada en el método run() de la misma. Finalmente se cambiará el valor de la variable booleana, de forma que la próxima vez que se llame al método startApp() se sepa que se trata de una llamada producida al salir de una pausa.
o Si no es la primera vez que se llama al método startApp(), entonces se prosigue con la ejecución de la tarea realizada por la hebra, desde el punto en que se quedara parada previamente como consecuencia de la pausa. Cuando la tarea se finaliza, se fuerza la destrucción del MIDlet, mediante la llamada a destroyApp(true). El argumento true pasado a destroyApp indica que se busca liberar todos los recursos que el MIDlet pudiera estar usando.
El método pauseApp() se invoca al producirse una llamada telefónica, por ejemplo. Para forzar este evento hay una opción concreta del menú MIDlet de KToolbar. Al recibirse la llamada a este método, se muestra un mensaje para seguir la traza de funcionamiento. Se imprime el estado de trabajo de la tarea auxiliar (de la cuenta) y se
fuerza a que la hebra deje de trabajar. Este es el objetivo de la llamada tarea.interrumpir().
Como no se sabe aún lo suficiente como para construir interfaces de usuario (aunque
pronto se sabrá), todos los mensajes se enviarán a la salida estándar. Se incluye a
continuación el código correspondiente, y seguidamente se verá cómo generar el suite,
tanto de forma manual como automática.
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class EjemploMIDlet1 extends MIDlet{
Tarea tarea;
boolean primeraVez;
// Constructor por defecto de la clase
public EjemploMIDlet1(){
String color=getAppProperty("color");
System.out.println("\n\n\nConstruido MIDlet con color: "+color);
primeraVez=true;
}
// Metodo para iniciar el funcionamiento del MIDlet
public void startApp() throws MIDletStateChangeException{
System.out.println("Metodo startApp");
if (primeraVez == true){
System.out.println("Ejecucion la primera vez.......");
System.out.println("Se inicia cuenta larga para
permitir pausar");
tarea=new Tarea();
tarea.start();
primeraVez=false;
}
else{
// Se reanuda la ejecucion tras salir de la pausa
System.out.println("Llamada tras pausa..... Valor de i:
"+tarea.getI());
tarea.continuar();
// Se destruye el midlet cuando la tarea termine
if (tarea.getFinalizado() == true){
destroyApp(true);
}
}
}
// Metodo para detener el funcionamiento del MIDlet
public void pauseApp(){
System.out.println("Metodo pauseApp");
System.out.println("Valor de i en el momento de la pausa:
"+tarea.getI());
tarea.interrumpir();
}
// Metodo para destruir el MIDlet
public void destroyApp(boolean condition){
System.out.println("Metodo destroyApp. Condicion: "+condition);
if (condition == true){
// Se indica la finalizacion del midlet
notifyDestroyed();
}
}
}
class Tarea extends Thread{
int i;
boolean interrumpido;
boolean finalizado;
Tarea(){
i=0;
interrumpido=false;
finalizado=false;
}
public void run(){
for(; i < 9000000; ){
if (interrumpido == false){
i++;
}
else{
try{
sleep(100);
}
catch(InterruptedException e){
System.out.println("Problema al dormir hebra....");
}
}
//System.out.println("Valor de i: "+i);
}
// Se finaliza la tarea
finalizado=true;
}
// Metodo para obtener el valor de i
int getI(){
return i;
}
// Metodo para interrumpir
void interrumpir(){
interrumpido=true;
}
// Metodo para continuar
void continuar(){
interrumpido=false;
}
// Metodo para acceder al valor de finalizado
boolean getFinalizado(){
return finalizado;
}
}
El código completo de este MIDlet puede descargarse directamente desde aquí:
EjemploMIDlet1.java Se trata de un MIDlet muy sencillo, que permitirá practicar con
los procedimientos de generación de MIDlets, así como los posibles estados en que
puede encontrarse un MIDlet en ejecución: pausa, activo y destruido.
Uso de KToolbar
Seguiremos el proceso completo de trabajo sobre el MIDlet incluido anteriormente. El
primer paso consistirá en ejecutar la herramienta KToolbar. Esta aplicación se encuentra
en la instalación de Wireless Toolkit. Para ejecutarla haremos lo siguiente (si no
funciona, avisad al profesor.......).
ktoolbar
La ventana principal de KToolbar tiene la siguiente aparencia:
Crearemos un proyecto de suite, en el que incluiremos el MIDlet generado con
anterioridad. Para ello se pulsa en el botón New Project. Al pulsar sobre él aparecerá la
siguiente ventana:
Como se ve, hemos rellenado la información de ambos campos de texto. Como nombre
del proyecto podemos elegir cualquiera, sin necesidad de coincidir con el nombre de la
clase principal del MIDlet. En el segundo campo de texto hemos de especificar el
nombre de la clase principal del suite que queremos ejecutar en el emulador. En este
caso es EjemploMIDlet1. En cuanto se pulsa el botón Create Project aparecerá una
nueva ventana donde aparecen informaciones relativas al MIDlet.
Al mismo tiempo, en la ventana principal de KToolbar han aparecido varios mensajes:
Estos mensajes indican que se ha creado la estructura de directorios necesaria para el
proyecto, y que las clases que queramos formen parte del MIDleet habrá que ubicarlas
en el directorio src; recursos adicionales (como iconos) irán en el directorio res y las
librerías (si las hubiera) en el directorio lib. Como se ve, el directorio del proyecto se
crea en el directorio de instalación de la herramienta, bajo el subdirectorio apps. En
nuestro caso, la ruta completa será $HOME/java/WTK2.2/apps/ejemplo1. Nuestro
primer MIDlet usará un icono muy sencillo (descargadlo aquí: iconoPeq.png).
Por tanto, lo primero que haremos será copiar el archivo con la clase asociada al MIDlet
en el directorio $HOME/java/WTK2.2/apps/ejemplo1/src/. El icono se ubicará en el
directorio $HOME/java/WTK2.2/apps/ejemplo1/res/. Dentro de este directorio
crearemos a su vez el directorio icons. Y en él será donde se guarde el archivo png del
icono. Para indicar que el icono del MIDlet es este, debe modificarse la información
sobre el icono. Para ello se pulsa el botón Settings de KToolbar. Aparecerá la venta
siguiente:
Aprovechamos ahora para indicar que deseamos que el MIDlet sea conforme a
MIDP1.0. Para ello se selecciona esta opción de las disponibles al pulsar sobre Target
Platform. Para indicar el icono asociado, se selecciona la pestaña MIDlets. Una vez
hecho esto aparecerá
Para poder cambiar el icono (el valor presente en la figura anterior se introduce por
defecto), basta con seleccionar la línea con los datos (la fila que aparece rellena), con lo
que se marcará con un color diferente para indicarnos que está seleccionada:
Ahora basta con pulsar sobre el botón Edit, lo que dará lugar a la aparición de la
ventana de edición:
Sobre esta ventana, en el recuadro Icon escribiremos /icons/iconoPeq.png, tal y como
se aprecia a continuación:
Al finalizar se pulsa sobre el botón Aceptar de la ventana de edición. Con esto queda
registrado el cambio de la propiedad correspondiente al icono del MIDlet:
Y pulsando sobre el botón OK desaparece la ventana de propiedades. Esto es todo lo
necesario para poder generar y ejecutar el MIDlet. En primer lugar, procedemos a
generar las clases a partir del código fuente. Para ello se pulsa el botón Build. Si todo ha
ido bien, aparecerá un mensaje indicado que la generación se realizó de forma correcta.
En caso de haber errores, se mostrarán en la ventana principal de KToolbar.
En cuanto se ha generado el MIDlet, podemos ejecutar mediante el botón Run. Al
pulsarlo, aparecerá el emulador con el MIDlet listo para ejecución.
Para lanzar la ejecución del MIDlet se pulsa sobre la tecla bajo el mensaje Launch. En
cuanto se produce esto el MIDlet se crea y el dispositivo invoca al método startApp().
Esto explica los mensajes que se aprecian en la consola de KToolbar:
Se muestra el mensaje de traza puesto en el constructor, indicando que la propiedad
color no está definida. Arreglar esto se deja para más adelante. También se aprecia la
traza ubicada a la entrada del método startApp(), que ha sido invocado por el sistema
de gestión de ejecución de MIDlets del dispositivo móvil. Los dos mensajes que
aparecen a continuación son trazas que muestran que el MIDlet se ejecuta por primera
vez.
Para pausar el MIDlet, tras unos segundos de funcionamiento, basta con actuar sobre el
menú MIDlet del emulador telefónico y seleccionar la opción Pause. Al hacerlo el
emulador queda de la forma siguiente:
A su vez, en la consola de KToolbar veremos los siguientes mensajes:
Las nuevas líneas de traza indican que se ha invocado al método pauseApp(). Como
comentamos previamente, esto ocurrirá al producirse una llamada de teléfono sobre el
móvil, por ejemplo. Se observa el valor de la cuenta en el momento en que se produjo la
pausa. Para continuar ejecutando el MIDlet (lo que ocurriría al finalizar la llamada),
forzamos la salida del modo de pausa. Para ello volvemos a actuar sobre el menú
MIDlet, seleccionado la opción Resume. Esto hace que aparezcan nuevas líneas de
traza indicando que se ha producido una nueva llamada al método startApp(), pero sin
tratarse de la primera llamada al mismo.
Por su parte, del emulador desaparece la indicación de llamada entrante:
Si se observa el código del método startApp(), se aprecia que la destrucción del MIDlet
sólo se producirá en el caso en que ya haya finalizado la tarea de cuenta. Para
asegurarnos que esto ocurre, tras la salida del modo de pausa esperaremos unos
segundos, se genera una nueva pausa (pulsando, como se indicón previamente, sobre la
opción Pause del menú MIDlet) para, a continuación forzar, mediante Resume (en el
menú MIDlet), una nueva llamada a startApp() una vez finalizada la cuenta. Cuando
esto ocurra, tendremos:
Sólo cuando el MIDlet haya sido destruido de forma completa podrá volver a lanzarse
de forma correcta.
EJERCICIO 1: probad qué ocurre cuando se intenta lanzar de nuevo la ejecución del
MIDlet antes de que haya finalizado completamente la tarea de cuenta. Justificad el
comportamiento observado.
Cuando se usa destroyApp(false) permite que el método compruebe si se cumplen las
condiciones necesarias para finalizar o no. En caso de no cumplirse, puede generar una
excepción del tipo MIDletStateChangeException, lo que genera a su vez una nueva
llamada startApp().
EJERCICIO 2: se propone que modifiquéis el código del MIDlet anterior de la forma
siguiente:
Montad un nuevo proyecto, ejemplo2, para trabajar sobre esta variante. La clase del MIDlet se denominará EjemploMIDlet2. Podéis partir de la clase EjemploMIDlet1 y modificarla.
En el método startApp(), en caso de no ser la primera llamada, después de la sentencia tarea.continuar(), se realiza la llamada a destroyApp(false). Esta llamada habrá que encerrarla en un bloque try-catch, ya que el método destroyApp() podría decidir generar la excepción si considera que el MIDlet no debe finalizar.
Modificad el método destroyApp(), de forma que en caso de recibir como argumento false, compruebe si la tarea ha finalizado o no. Si no ha finalizado, lanza una excepción del tipo MIDletStateChangeException, para dar tiempo a que la tarea de conteo finalice. Si la tarea ha finalizado, se llama al método notifyDestroyed(), con lo que el MIDlet indica que desea finalizar.
En nuestro caso, el MIDlet usa un valor de atributo (color). Si se observa el código, se
comprobará que al imprimir su valor se muestra null. Si se intenta manejar esta
propiedad, sin haberla especificado de forma explícita, puede ocurrir un error como el
mostrado a continuación:
Pero, ¿cómo se define este atributo?. Para ello usaremos el botón Settings. Cuando
aparezca la ventana de propiedades del MIDlet, seleccionaremos la opción User
Defined, que permitirá definir atributos propios. Sobre esta ventana, pulsaremos el
botón Add.
Al pulsar sobre Add aparecerá la ventana que hemos de usar para definir el valor de la
propiedad deseada:
Se escribe el nombre de la propiedad (color) y se pulsa sobre Aceptar. Con esto la
ventana de propiedades queda de la siguiente forma:
Se pincha sobre el campo de texto en blanco y se introduce el valor deseado:
Pulsamos OK y ya podemos volver a ejecutar el MIDlet. Ahora la traza inicial indica:
EJERCICIO 3: probad con los MIDlets de demo que vienen con la herramienta.
Activad la monitorización, activando las preferencias (Edit + Preferences + Monitor)
deseadas. Con esto podéis haceros una idea de la capacidad de la plataforma de
desarrollo. Haced un pequeño guión con indicaciones sobre vuestra opinión al respecto:
demos más interesantes, limitaciones, puntos fuertes, etc.
www.youtube.com/watch?v=YrtANPtnhyg&feature=player_embedded
video
dev.wsnetcorp.com
tecnología SixthSense y su potencial Publicado el 16 julio, 2012 / Autor: Webmaster
Hace unos días un colega de hace años me compartio algo nuevo que me parecio
increible aunque al mismo tiempo con sus partes que se podrian mejorar
(principalmente el ajuste de enfoque en los elementos que por ahi creo se podría trabajar
bastante). Este nueva tecnología es móvil y autoajustable a cualquier objeto de la vida
real (hasta donde pude ver soy sincero ) permitiendonos intercatuar con todo en
nuestra vida real a través de “Gestos” mayormente con nuestra manos y controlar así de
esa manera las diferentes opciones que esta trae. Para que hablar más aqui dejo el enlace
para que juzguen por si mismo (cualquier error en definición es parte mia y no de la
tecnología y lo que me sorprende es que tenga desde el 2009 y no ha sido un
BOOOMMM!, porqué será?)
Definición de imágenes responsive como atributo de img o nuevo
elemento picture? Publicado el 17 mayo, 2012 / Autor: Webmaster
Uno de los grupos de trabajo para la definición del Standard HTML5 (WHATWG) ha
estado debatiendo sobre la mejor forma de implementar imágenes responsive con las
cuales se puedan manejar diferentes versiones de imágenes bajo un mismo
atributo/etiqueta, al día de hoy el Encargado de mantener y actualizar el Standard
HTML5 para la WHATWG (Ian Hickson) ha tomado la descisión de incluir esta
capacidad como atributo de la ya conocida etiqueta <img> a través del atributo srcset
mientras tanto en el Responsing Images Working Group que fue sugirido crearse para
tal hecho se miranban respuestas positivas por el uso de la nueva etiqueta <picture>
(semejante a la etiqueta video y audio que incluyen sus etiquetas hijas source) a lo cual
se tiene una interesante conversación de porque no se tomo en cuenta a la comunidad de
Desarrolladores en esta descisión aqui (en inglés).
En este otro hilo se puede ver la manera en que la W3C (el otro grupo trabajando en un
Standard HTML5 también) ha enfocado sus esfuerzos (también con la utilización de
CSS) para la utilización de imágenes Responsive.
Referencia elemento picture : <picture>
Definición atributo srcset por la WHATWG
Publicado en HTML5 / CSS3, Móviles | Etiquetado guatemala, html5, img, picture, srcset
image-set | Dejar un comentario
HTML5: elementos figure y figcaption Publicado el 13 mayo, 2012 / Autor: Webmaster
Entre otros de los nuevos elementos HTML5 que tenemos a nuestra disposición estan
los elemento <figure> y <figcaption> .
Estos nuevo elemento nos permiten definir una mejor semántica (significado o sentido)
a nuestro contenido dentre de un documento HTML5; En el caso de estos elementos en
específico nos permitiran anotar o resaltar ilustraciones, diagramas o fotos que son
referenciados directamente desde el contenido principal. Estas etiquetas podriamos
utilizarlas en Diagramas, imágenes, fotos que acompañan el texto principal de nuestro
contenido.
La etiqueta <figcaption> es únicamente para enmarcar un titular dentro de la etiqueta
<figure>.
Uno de los puntos importantes a tomar en cuenta al momento de utilizar estas etiquetas
es por ejemplo el caso a continuación; Si pudieramos remover totalmente esta etiqueta
del contenido principal y aún así el contenido podría seguir dando el sentido y la idea
del tema que se esta hablando sin necesidad de sobreescribirlo por excluir esta
imagen entonces esta etiqueta no es la indicada para utilizarse, en ves podriamos
utilizar una etiqueta <aside> u otra relacionada.
Al momento de utilizarlas, el contenido debe ir fuertemente relacionado a la
representación de la imagen que va incluida entre estas etiquetas.
Ejemplo de su correcta utilización:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<article>
<hgroup>
<h1>Titular principal</h1>
<h2>Subtitular</h2>
</hgroup>
<p>contenido de nuestro articulo</p>
<p>Como podemos ver en este artículo la referencia principal a una
nueva etiqueta HTML5 y es parte de los nuevos standares Web 2.0 como
puede ver en el gráfico a continuación </p>
<figure id="figura1">
<figcaption>Tabla de standares Web</figcaption>
<img src="images/tabla-de-standares-web20.png" width="200"
height="400" alt="tabla de standares" />
</figure>
</article>
Como se puede ver en el ejemplo anterior la imagen referenciada entre las etiquetas
figure y figcaption van fuertemente relacionadas al contenido principal, sin esta imagen
el contenido tendria que ser re-escrito para poder proveer el significado exacto y no
dejar lagunas de información sin aclarar, este es el uso adecuado de estas nuevos
elementos HTML5.
Publicado en HTML5 / CSS3 | Etiquetado figcaption, figure, html5, img, semantica | 1
Comentario
Certificado Comodo Elite SSL Publicado el 7 mayo, 2012 / Autor: Webmaster
Instalando un certificado Comodo Elite SSL (si lo see, es mejor el EV SSL para mayor
credibilidad de la empresa y Comodo es más cuidadoso en verificar todo lo referente a
cuestiones financieras, fiscales etc. además del reconocido Green Bar en la barra de
direcciones de los navegadores) pero al recibir dicho certificado me voy dando cuenta
que no venia el ROOTcrt dentro del Zip!, entonces me puse a la tarea de buscarlo en
soporte de Comodo y lo he encontrado en el siguiente Link
https://support.comodo.com/index.php?_m=downloads&_a=viewdownload&downloadi
temid=10&nav=0,1,5. El ROOT nos servirá para que nuestro CA pueda firmar nuestro
CRT de otro modo al momento de instalarlo tendremos el mensaje de The CA
certificate does not sign the certificate, al incluir el ROOT seguido del CA y nuestro
CRT tendremos todo instalado exitosamente.
PD: lo he puesto en PHP mientras resuelvo incluir una sección adicional donde este tipo
de temas puedan ser mejor clasificados
Publicado en PHP / GTK | Etiquetado certificado SSL, comodo, instalación Comodo SSL, venta
en linea | Dejar un comentario
Introducción HTML5 y CSS3 Publicado el 3 mayo, 2012 / Autor: Webmaster
En esta nota presentaré una descripción introductoria de las nuevas caracteristicas,
etiquetas y APIs disponibles en HTML5 y CSS3. Esta nota no pretende ser una
descripcion exaustiva de lo nuevo de estas tecnologías (lo cual se irá tratando en otros
temas en esta misma sección) por lo cual si desean tener todos los detalles de dichas
tecnologias pueden visitar las dos grupos de trabajo que actualmente estan en el proceso
de definicion de los estandares de dichas tecnologias las cuales son: WHATWG (Web
Hypertext Application Technology Working Group) y W3C (World Wide Web
Consortium).
En el camino de definir aplicaciones web mas rápidas, eficientes y mantenibles se
empezo con el desarrollo de 2 especificaciones web las cuales fueron Web Forms 2.0 y
Apps 1.0 que vinieron a satisfacer las exigencias y cambios que ocurrieron en el campo
del desarrollo Web. Estas tecnologías fueron las que guiaron a la definición de lo que
ahora conocemos como HTML5.
Una de las ventajas de HTML5 es que ahora se cuenta con elementos mas semanticos lo
cual dan más significado al contenido HTML de las páginas Web desarrolladas como
son las nuevas etiquetas: <header>, <nav>, <aside>, <section>, <article>, <footer>,
<optgroup>, <figure>, <figcaption>, <mark>, <progress>, <meter>, <time>, <video>,
<audio> entre otros, si no que también este código es más entendible por humanos
como también por los robots/arañas que se encargan de indexar los contenidos de
páginas web en la Internet además que HTML5 incluye APIs que permiten y facilitan el
trabajo con elementos en nuestros documentos, como lo son en atributos del elemento
<form> (se escribirá sobre es tema en detalle más adelante) para validaciones y plugins
como Flash Player para la reproducción de video por ejemplo entre otras
funcionalidades.
Entre otros de los cambios que trae la nueva definición estan que ya no es requerido
definir del DOCTYPE de nuestro documento HTML, basta con incluir <!DOCTYPE
html> lo cual indica que es un documento HTML5. Otro cambio es el que no es
requerido encerrar nuestros atributos entre comillas como lo exigia el XHTML 1.o,
nuestro atributos pueden quedar como <p class=miclase> a excepción cuando nuestro
elemento lleve definido mas de un valor para dicho atributo en dicho caso deberemos
encerrar entre comillas nuestros valores de dicho atributo. Los elementos como <br />
ya no es necesario que lleven la barra que indica que es un elemento sin contenido a lo
cual podemos definirlo como <br>. Atributos de formulario como <input type=”text”
readonly=”readonly”/> no es obligatorio que se defina de esa manera, ahora podemos
definirlo como <input type=text readonly> al igual el atributo type ya no es requerido
en las definiciones de estilos CSS y Scripts Javascript (y también nunca lo fue, sólo para
validación del documento si no recuerdo mal) y si asi lo deseamos podemos escribir las
etiquetas en en cualquier tipo de letra, bien puede ser InPuT, input, Input que todos son
lo mismo en HTML5 entre otros cambios a tratarse en futuras notas.
Por otro lado CSS3 que sigue definiendo como el código HTML es presentado y/o
estilado en los navegadores (ya sean en PC o dispositivos móviles). CSS3 incluye
nuevas características que dan soporte a nuevos selectores, Sombras, bordes
redondeados, fondos multiples en contenedores, animaciones, transparecias entre otros.
Anteriormente para lograr el uso de alguna de las características antes mencionadas
teniamos que recurrir a técnicas que ivan desde hacks CSS, usar elementos extras
HTML y/o imágenes para lograr border redondeados en algun contenedor entre otros ya
que no habia otra forma de lograr dichos resultados. Las especificaciones de CSS3 se
encuentran aún en el proceso que todos los desarrolladores de navegadores las adopten,
es por ello que encontramos propiedades CSS3 diferentes en algunos navegadores como
en Firefox y aquellos que utlizan el Webkit, por ejemplo y para hacer notar este punto
de la falta de definición de unestandar final CSS3 encontramos la propiedad moz-
transform en Firefox y webkit-transform para navegadores basados en WebKit, esto por
el motivo que aún esta definición de CSS3 no se encuentra completa y aún queda
camino por liberar una definición final.
HTML5 y CSS3 son herramientas importantes para considerar en nuestra curva de
aprendizaje ya que estas tecnologías estan siendo bien aceptadas por el mercado de
dispositivos móviles por su dinamísmo y funcoinalidades que se incorporan por defecto
en dichos estandares lo cual la mayoria de tecnologías móviles ya han adoptado.
En futuras notas se trataran a detalles temas relacionados a estas Tecnologías.
Publicado en HTML5 / CSS3 | Etiquetado CSS3, html5, móviles, web 2.0, Web Forms 2.0 web
Aps 1.0 | Dejar un comentario
Manejo de Javscript y PHP en plantillas de Smarty Publicado el 2 mayo, 2012 / Autor: Webmaster
Al empezar a utilizar el gestor de plantillas Smarty nos encontraremos con la necesidad
de ejecutar código Javascript o PHP para poder implementar alguna funcionalidad que
desde nuestro controlador no podemos ejecutar (si usamos MVC en este caso seria el
archivo PHP que se encarga de procesar las solicitudes del cliente y hacer los
respectivos llamados a nuestros Objetos y acceso a datos) ya que no viene siendo el
lugar más indicado, como para decir, definir código javascript. Es pór ello que Smarty
nos da casi las mismas funciones de control de flujo de nuestra programación para poder
implementarla en nuestro TPLs y asi poder tomar la descisión de lado de nuestros
templates.
Empezaré por dar un pequeño ejemplo de como podemos ejecutar Javascript en nuestras
plantillas sin tener problemas con las definiciones de llaves (en definición de funciones)
que es uno de los problemas que podremos encontrar. (La nueva versión de Smarty tres
ya soluciona esto por defecto)
Cuando a código Javascript respecta este debemos acostumbrarlo a encerrar entre
nuestras etiquetas de Smarty {literal} el cual nos permite “tomar un bloque de
información literalmente en porciones de código Javascript y CSS donde las llaves
interferirian con los delimitadores de identificativos de Smarty, todo lo que este entre
{literal} y {/literal} será desplegado tal como es”
Ejemplo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{literal}
<code>
<script type="text/javascript"></code>
//<![CDATA[
function miFuncion(dato){
alert('el parametro de la función es '+ dato);
return;
}
//]]>
</script>
{/literal}
en el ejemplo anterior nuestras llaves no interferirian con la definición de etiquetas
Smarty.
Ahora qué pasa cuando necesitamos ejecutar código PHP dentro de una de nuestras
plantillas?
En este caso tomar nota que tenemos al igual que literal una etiquetas para poder
ejecutar PHP puro dentro de nuestro .tpl la cual es {php}{/php}.
Esto es util para cuando necesitamos, por ejemplo utilizar uno de nuestros objetos PHP
dentro del .tpl con lo cual tendriamos dos alternativas:
1. asignar el objeto desde nuestro controlar con $smarty->assign_by_ref($miobjeto);
2. usar las etiquetas de {php} y usar include para crear nuestro objeto y utilizarlo como
normalmente se hace en PHP.
plantilla.tpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{* código a continuación *}
{php}
include_once('archivoobjeto.php');
$objeto = new creaObjeto(); // si nuestro
{/php}
<div style="" onclick="funcionjavascript()">contenido de nuestro
contenedor y nuestro objeto es {php} $objeto->metodo1(); {/php}</div>
Y por último alguna ves se nos dará la ocasión en que necesitemos referencias o crear
código javascript dinámicamente, a lo cual, OJO no debemos encerrar nuestros script
dentro de {literal} ya que interpretaria las etiquetas {php} como tales. Entonces
debemos hacer como el ejemplo básico a continuación:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type="text/javascript">
//<![CDATA[
function miFuncion(){
alert('el parametro de la función es '+ {php} echo $datoPHP; {/php});
return;
}
//]]>
</script>
lo cual si permitirá a nuestra plantilla interpretar el PHP sin ningún problema.
Como alternativa (y es la que uso actualmente la cual no me ha dado problema) es
configurar tus etiquetas de Smarty para que sean dobles, o sea cada porción de código
iria {{php}} {{/php}} y no he encontrado problema alguno en las mezclas antes
mencionadas.
Además solo queda esperar la versión 3 de Smarty la cual se dice evitará estos dolores
de mente al tener extensos script y objetos php :=)
Publicado en PHP / GTK | Etiquetado php, php y smarty, smarty, smarty tags | Dejar un
comentario
Crear archivo css (con extensión CSS y no PHP) desde PHP Publicado el 2 mayo, 2012 / Autor: Webmaster
Tuve la necesidad de crear dinámicamente un archivo CSS desde PHP, consultando
muchas fuentes todas eran las mismas soluciones, crea un archivo PHP donde le pasas
variables PHP etc, etc. El problema es que mi archivo CSS debia ser consumido por otra
aplicación (wp e commerce de WordPress para un tema dinámico) y dicha aplicación
obligatoriamente esperaba un archivo con extensión .css a lo cual me puse a la tarea de
buscar una solución, y vine con este código de a continuación
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// **********************************
// extending for dynamic creation of wp e commerce stylesheet
global $blog_id;
if( $blog_id == 144 ){
$archivo = fopen('/var/www/vhosts/xxxxxxxxxx.com/httpdocs/wp-
content/blogs.dir/'.$blog_id.'/files/wpsc/themes/xxxxxx1/'.get_option(
'wpsc_selected_theme').'.css', 'w');
require_once('/var/www/vhosts/xxxxxxxxxx.com/httpdocs/wp-
content/blogs.dir/'.$blog_id.'/files/wpsc/themes/xxxxxxxxx/xxx_shop_st
ylesheet.php');
fwrite($archivo, $estilo);
}
// ***********************************
prácticamente lo que hago aqui es que desde un archivo php genero mi código css el
cual lo asigno a una variable (o bien podriamos guardar el contenido en cache con
ob_start etc) luego incluyo dicho archivo y lo asigno como contenido a mi archivo css
creado con fopen y fwrite.
Publicado en PHP / GTK | Etiquetado crear css desde php, css, php, php y css | Dejar un
comentario
Buscador por categorías de productos en WP E-COMMERCE 3.7.8 Publicado el 2 mayo, 2012 / Autor: Webmaster
Este es un pequeño código SQL que me he creado para poder implementar un buscador
de productos por categorías. La idea es tener un formulario el cual consta de un
elemento SELECT que contendrá las categorías principales creadas en nuestro
administrador de la tienda y un elemento INPUT donde introduciremos el texto a buscar
en nuestros productos.
SQL para listar las categorías de nuestra tienda:
1
$categories = $wpdb->get_results('SELECT id, name, image FROM
'.WPSC_TABLE_PRODUCT_CATEGORIES.' WHERE category_parent = 3 ORDER BY
name ASC', ARRAY_A);
En esto caso lo estoy limitando a las sub-categorías de una categoría en específico
Luego nuestro código que efectua la búsqueda:
1
2
3
4
5
6
7
8
9
10
11
12
13
$file_datas = $wpdb->get_results("SELECT pl.name prodname, pl.price
prodprice, IF(pl.additional_description > '',
pl.additional_description, \"No disponible\") additional, pl.id
prodid, pi.*, pf.* FROM ".WPSC_TABLE_PRODUCT_LIST." pl
LEFT JOIN ".WPSC_TABLE_PRODUCT_IMAGES." pi ON pl.id = pi.product_id
LEFT JOIN ".WPSC_TABLE_ITEM_CATEGORY_ASSOC." ON pl.id =
".WPSC_TABLE_ITEM_CATEGORY_ASSOC.".product_id
INNER JOIN ".WPSC_TABLE_PRODUCT_FILES." pf ON pl.id = pf.product_id
AND pl.file = pf.id
WHERE pf.preview != '' AND pf.filename != '' AND
wp_wpsc_item_category_assoc.category_id = ".$wpdb-
>escape($_GET['searchcategory'])."
AND pl.name LIKE '%".$wpdb-
>escape(stripslashes($_GET['categorytext']))."%' OR
pl.additional_description LIKE '%".$wpdb-
>escape(stripslashes($_GET['categorytext']))."%'
AND pl.active = 1 AND pl.publish = 1 GROUP BY pl.id ORDER BY pl.name
ASC", ARRAY_A);
al haber ejecutado este código lo único que nos faltará es hacer un bucle sobre los
registros devueltos por nuestro Query.
Publicado en MySQL, PHP / GTK | Etiquetado categorieas, php, query categorias, wordpress,
wp e commerce | Dejar un comentario
Programar Credomatic REST Webservice y WP E commerce Publicado el 2 mayo, 2012 / Autor: Webmaster
Ahi por el 28 de mayo tuve que efectuar la migración del famoso CGI de Credomatic
hacia el nuevo servicio (webservice) que entro en efecto desde el 1 de Junio de 2011
para nosotros en GUatemala. La implementación que efectue fue utilizando siempre
wordpress como CMS y WP E Commerce como plataforma de comercio electronico. La
usabilidad y configuración de dicho webservice debia quedar configurable (user id,
private key, y public key) desde la interfaz de settings de dicho plugin. a lo cual pego el
código utilizado para extender el plugin y dar la capacidad con Credomatic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<?php
$nzshpcrt_gateways[$num]['name'] = 'Credomatic';
$nzshpcrt_gateways[$num]['admin_name'] = 'Credomatic';
$nzshpcrt_gateways[$num]['internalname'] = 'credomatic';
$nzshpcrt_gateways[$num]['function'] = 'gateway_credomatic';
$nzshpcrt_gateways[$num]['form'] = "form_credomatic";
$nzshpcrt_gateways[$num]['submit_function'] = "submit_credomatic";
$nzshpcrt_gateways[$num]['payment_type'] = "credomatic";
if(in_array('credomatic',(array)get_option('custom_gateway_options')))
{
$gateway_checkout_form_fields[$nzshpcrt_gateways[$num]['internalname']
] = "
<tr>
<td>Número tarjeta crédito: *</td>
<td>
<input type='text' value='' name='ssl_card_number' />
<p class='validation-error'></p>
</td>
</tr>
<tr>
<td>Expiración tarjeta de crédito: (MMYY) *</td>
<td>
<input type='text' name='ssl_exp_date' size='4'>
<p class='validation-error'></p>
</td>
</tr>
<tr>
<td>CVV *</td>
<td><input type='text' size='4' value='' maxlength='4'
name='ssl_cvv2cvc2' />
<p class='validation-error'></p>
</td>
</tr>
";
}
function gateway_credomatic($seperator, $sessionid) {
global $wpsc_cart;
$transact_url = get_option('transact_url');
$_SESSION['wpsc_sessionid'] = $sessionid;
//exit('<pre>'.print_r($_POST,true).'</pre>');
$unixtime = time();
$form_action =
'https://paycom.credomatic.com/PayComBackEndWeb/common/requestPaycomSe
rvice.go';
// select last inserted sale id and sum 1 to get the next id to pass
it to credomatic.
//+++++++++++++++++++
// ebe modified, 2011 may 31 .. added new Credomatic Payment gateway.
global $wpdb;
//$rs = $db->Execute('select ( max(orders_id) +1) as nextid from
orders');
//$row = $rs->fields;
// $cmd = $row['nextid']; // next insertion id
//set POST variables
$url =
'https://paycom.credomatic.com/PayComBackEndWeb/common/requestPaycomSe
rvice.go';
$unixtime = time();
//session_start();
//print( number_format($order->info['total'] *
MODULE_PAYMENT_CC_IN_GTQ, 2, '.', '') ) ; exit;
// $_SESSION['zen_id'] = $_REQUEST['zenid'];
$un = unserialize( $_SESSION['wpsc_cart'] );
$rs = $wpdb->get_results('select ( max(id)) as actual_id from
wp_wpsc_purchase_logs');
$strCookie = 'sessionid='.$_SESSION['wpsc_sessionid'].';
sale_id='.$rs[0]->actual_id;
session_write_close();
$fields = array(
'username'=>urlencode("usuarioaqui"),
'type'=>urlencode("auth"),
'key_id'=>urlencode("key_id_aqui"),
//'hash'=>urlencode(md5($row['nextid'].'|'.number_format(($order-
>info['total'] * MODULE_PAYMENT_CC_IN_GTQ), 2, '.',
'').'|'.$unixtime.'|provatekeyaqui____')),
'hash'=>urlencode(md5($rs[0]-
>actual_id.'|1.00|'.$unixtime.'|private_key_aqui')),
'time'=>urlencode($unixtime),
'redirect'=>urlencode("http://miweb.com/products-page/transaction-
results/"),
//'amount'=>urlencode(number_format(($order->info['total'] *
MODULE_PAYMENT_CC_IN_GTQ), 2, '.', '')),
'amount'=>urlencode('1.00'),
'orderid'=>urlencode( $rs[0]->actual_id ),
'ccnumber'=>urlencode($_POST['ssl_card_number']),
'ccexp'=>urlencode( $_POST['ssl_exp_date'] )
);
//https://www.miweb.com/zen-cart/index.php?main_page=checkout_payment
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .=
$key.'='.$value.'&'; }
rtrim($fields_string,'&');
//print_r($fields); exit;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIE, $strCookie );
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//print_r($result); exit;
$unixtime = NULL;
//close connection
curl_close($ch);
exit;
//+++++++++++++++++++++++++++ / end ebe modified
}
function submit_credomatic() {
if($_POST['ssl_user_id'] != ''){
update_option('ssl_user_id', $_POST['ssl_user_id']);
}
if($_POST['ssl_publickey_id'] != ''){
update_option('ssl_publickey_id', $_POST['ssl_publickey_id']);
}
if($_POST['ssl_privatekey_id'] != ''){
update_option('ssl_privatekey_id', $_POST['ssl_privatekey_id']);
}
return true;
}
function form_credomatic() {
if(get_option('ssl_user_id')!=''){
$ssl_user_id = get_option('ssl_user_id');
}else{
$ssl_user_id = '';
}
if(get_option('ssl_publickey_id')!=''){
$ssl_publickey_id = get_option('ssl_publickey_id');
}else{
$ssl_publickey_id = '';
}
if(get_option('ssl_privatekey_id')!=''){
$ssl_privatekey_id = get_option('ssl_privatekey_id');
}else{
$ssl_privatekey_id = '';
}
$output = "<tr>\n\r";
$output .= "<td>\n\r<label for='ssl_user_id'>".__('ID
Usuario','wpsc')."</label></td>";
$output .= "<td><input type='text' id='ssl_user_id'
value='".$ssl_user_id."' name='ssl_user_id' /></td>";
$output .= "</tr><tr>";
$output .= "<td>\n\r<label for='ssl_publickey_id'>".__('Key ID
publico','wpsc')."</label></td>";
$output .= "<td><input type='text' id='ssl_publickey_id'
value='".$ssl_publickey_id."' name='ssl_publickey_id' /></td>";
$output .= "</tr><tr><td>";
$output .= "<label for='ssl_privatekey_id'>".__('Key ID
privada','wpsc')."</label></td>";
$output .= "<td><input type='text' id='ssl_privatekey_id'
value='".$ssl_privatekey_id."' name='ssl_privatekey_id' />";
/*
$output .= "<label for='ssl_merchant_id'>".__('','wpsc')."</label>";
$output .= "<input type='text' id='' value='' name='' />";
*/
$output .= " </td>\n\r";
$output .= "</tr>\n\r";
return $output;
}
?>
verdaderamente se que hizo falta hacer configurable el redirect que utilizará credomatic, pero
con esto creo se tiene la base para completar y hacerlo mas amigable.Agrego a esto el que
debes crear tu archivo con el código puesto , e incluirlo en tu merchants folder para que ya
puedas configurar tu nuevo enlace de pago.
Publicado en MySQL, PHP / GTK | Etiquetado credomatic, credomatic en linea, credomatic
guatemala, guatemala, implementar, venta en linea | 1 Comentario
Punto de venta (PDV/POS) via Web Publicado el 2 mayo, 2012 / Autor: Webmaster
Desde hace algunos meses he estado trabajando en una gran versión del tan famoso
Punto de Venta que cualquier empresa dedicada a mercadear cualquier tipo de producto
necesita, este sistema esta desarrollado en PHP utilizando el Framework MVC
CodeIgniter y entre las características con las que contará este sistema será :
1. Manejo de inventario boga (ingresos, egresos a bodega)
2. Distribución de productos a tiendas (puntos de venta)
2. Manejo de pedidos a bodega desde las tiendas.
3. Inventarios en Tiendas
4. Manejo de clientes
5. Ventas por cliente o por Empresa (si en caso el cliente fuera corporativo)
6. Descuentos por venta (porcentajes %)
7. Manejo de proveedores a bodega
8. Reportes por tienda
9. Reportes de bodega
10. Reportes de ventas (tienda, fechas, producto)
Estas son algunas de las características con las que cuenta dicho sistema, hasta este
momento esta basado en GPL y próximamente estaré colocando un link de la demo de
dicho sistema.
Publicado en PHP / GTK | Etiquetado php, pos, POS php, punto de venta, web pos | Dejar un
comentario
top related