- La ausencia de parámetros, que es el estándar con el que lo encontramos, hace que se cargue la pantalla grafica, justamente lo que queremos evitar.
- play, nos cargara el apartado grafico en modo consola, todavía no he pillado muy bien para que sirve, la cuestión es que yo no he visto que descienda el consumo de RAM.
- stop, este parámetro evita que se cargue todo el apartado grafico, en este si que he podido ver una reducción en el consumo de memoria RAM.
Desactivar las X en nuestro Ubuntu Server 12.04
Ejecutar las macros de un XLSM desde Java
Vamos con algo muy sencillo pero que hasta que he encontrado la formula más sencilla he tenido que dar unas cuantas de vueltas. Se trata de la ejecución de macros desde Java, para eso tenemos dos maneras, hoy nos vamos a ocupar solamente de una, vamos a ejecutar una macro almacenada dentro de un Excel.
Lo primero que necesitamos es una API externa denominada JACOB que es un JAVA-COM bridge estas se utilizan normalmente para realizar llamadas a JNI (Java Native Interface) en este caso para poder realizar llamadas a las DLL que nos permite la ejecución de una macro, para ello nos tenemos que bajar el jar y el dll de la pagina de sourceforge donde se aloja el proyecto.
Ahora dentro del Eclipse, o el IDE que utilicéis para programar, tenemos que importar un nuevo JAR y a este asignarle el directorio en el que se encuentra el dll.
No os engañéis por el nombre, "LFR/lib/jacob.dll" es un directorio, no un fichero, solo que soy así de poco original.
Hay una cosa importante en este programa y es que tenéis que conocer como se llama la macro y en que pagina esta escrita ya que le tenéis que dar toda la ruta entera, de ahí que esto sea solamente un ejemplo, para tenerlo todo perfectamente programado todo esto tendría que estar parametrizado, preferiblemente desde base de datos, lo cual nos evita un pase a producción, y la función tendría que aceptar como parámetros de entrada diferenciados la ruta, el libro, la pagina y el nombre de la macro para poder montarlo nosotros de manera dinámica.
Veamos el código, os lo dejo para que podáis familiarizaros con el, es relativamente fácil, de todas maneras vamos a comentar los puntos claves para que se vea más claro.
package LFR.Liem.Dazkun.Test.Java.POIExecutor;
import java.io.File;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class POIExecutor {
/**
*
*
* @author Liem Dazkun
* @param file
* Fichero del que se ejecuta la macro
* @return boolean TRUE si se ejecuto correctamente la macro
*
*/
public boolean openFile(String file) {
try {
final String macroName = "!Hoja1.multiplica";
executeMacro(new File(file), macroName);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public boolean executeMacro(File file, String macroName) {
ComThread.InitSTA();
final ActiveXComponent excel = new ActiveXComponent("Excel.Application");
try {
final Dispatch workbooks = excel.getProperty("Workbooks")
.toDispatch();
final Dispatch workBook = Dispatch.call(workbooks, "Open",
file.getAbsolutePath()).toDispatch();
final Variant result = Dispatch.call(excel, "Run",
new Variant(file.getName() + macroName));
Dispatch.call(workBook, "Save");
com.jacob.com.Variant f = new com.jacob.com.Variant(true);
Dispatch.call(workBook, "Close", f);
} catch (Exception e) {
e.printStackTrace();
} finally {
excel.invoke("Quit", new Variant[0]);
ComThread.Release();
return true;
}
}
}
Bueno por lo que podemos ver openFile es la que hace la llamada a la macro en este caso es una macro que tengo almacenada en la 'Hoja1' y que se llama 'multiplica', por eso os decía que era muy importante saber como se llamaban las macros, después llamamos a una función denominada executeMacro con dos parámetros, el primero será el Excel al que le ejecutaremos la macro y el segundo será el nombre de la misma.
Cargaremos el Excel que es un 'ActiveXComponent', un objeto propiedad de la librería Jacob, y lo inicializaremos como un 'Excel.Application'. Después se cargara el libro sobre el que trabajaremos y en la siguiente línea se ejecutara la macro, salvamos el libro para asegurar que las modificaciones quedan almacenadas y cerramos el flujo de datos del JNI.
Con eso ya tendríamos toda la llamada a la macro de un Excel.
Para hacer tanto tiempo que no escribo nada no esta del todo mal, ha sido una investigación interesante de hacer.
Tabla de multiplicar para SAP ABAP IV
De todo hay que aprender y nada puede detenernos, ahora estoy estudiando algo de ABAP IV, como muestra os voy a dejar una tabla de multiplicar realizada bajo SAP ABAP IV.
SAP nos solicita de que numero solicitamos la tabla de multiplicar, tras ello hacemos un bucle para imprimir las diez multiplicaciones necesarias.
*&---------------------------------------------------------------------*
*& Report Z_LIEM_TEST
*&
*&---------------------------------------------------------------------*
*&
*& El programa solicita un numero y muestra su tabla de multiplicar
*&---------------------------------------------------------------------*
REPORT z_liem_test.
DATA resultado TYPE string.
DATA multi(17) TYPE c.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
PARAMETERS p_params TYPE i.
SELECTION-SCREEN END OF BLOCK b1.
IF p_params IS INITIAL.
WRITE 'No se ha indicado de que tabla quiere'.
ELSE.
WRITE p_params TO multi.
DO 10 TIMES.
DATA index(17) TYPE c.
DATA res(17) TYPE c.
DATA resu TYPE i.
resu = sy-index.
WRITE sy-index TO index.
MULTIPLY resu BY multi.
WRITE resu TO res.
CONCATENATE index ' * ' multi ' = ' res INTO resultado.
CONDENSE resultado.
WRITE resultado.
SKIP.
ENDDO.
ENDIF.
Como podemos ver es mucho código para este solo proceso, pero es un primer acercamiento al código seguiremos haciendo cosas para SAP ABAP IV :)
Crear un "Splash Screen" sencillo en Android
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textSize ="18sp"
android:text="@string/hello_world_2"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"
tools:context=".MainActivity"
/>
</RelativeLayout>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lfr.liem.dazkun.test.android.splashscreen"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".SplashScreen"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package lfr.liem.dazkun.test.android.splashscreen;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class SplashScreen extends Activity {
/** Se le llama cuando la actividad es creada por primera vez*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Creamos un objeto de tipo SplashHandler
SplashHandler mHandler = new SplashHandler();
//Le seteamos cual es el XML va a usar como configurador de la actividad
setContentView(R.layout.splash_activity);
//Creamos un objeto de tipo Message
Message msg = new Message();
//Asignamos un codigo unico al mensaje
//Despues este codigo sera utilizado para identificar el mensaje.
msg.what = 0;
//Enviamos el mensaje que durara 3 segundos (3000 = 3 seg)
mHandler.sendMessageDelayed(msg, 3000);
}
//La clase Handler implementa 'handle' el manejador de los mensajes
private class SplashHandler extends Handler {
//Este metodo se usa para manejar los mensajes recibidos.
public void handleMessage(Message msg)
{
final Intent intent = new Intent();
//switch del identificador del mensaje segun su codigo
switch (msg.what) {
case 0:
super.handleMessage(msg);
//Creamos un intent para arrancar la actividad
//Nuestra intención es comenzar MainActivity
intent.setClass(SplashScreen.this,MainActivity.class);
startActivity(intent);
// finalizamos la actual actividad
SplashScreen.this.finish();
break;
default:
//Duplicamos el codigo por que solo tenemos un splash screen
//si tuvieramos alguno que tuviera que salir en caso de fallo lo pondriamos aquí
super.handleMessage(msg);
intent.setClass(SplashScreen.this,MainActivity.class);
startActivity(intent);
SplashScreen.this.finish();
break;
}
}
}
}
El onCreate es como el que tendremos en cualquiera de nuestras actividades, sencillamente inicializa y llama a su XML el cual contendrá el texto que visualizaremos y la asignación del mensaje que visualizaremos.
El objeto Handler es un controlador de mensajes que nos enviara el mensaje durante tres segundos.
La clase SplashHandler lo que hace es crear un nuevo hilo que mostrara el nuestra pantalla de inicio, el objeto Intent se ocupara de realizar la transición desde nuestro "SplashScreen" a nuestra clase principal, startActivity(intent); arrancaria esa actividad mientras que SplashScreen.this.finish(); haría que nuestra actividad finalizara. El codigo se ha repetido dos veces aunque no sea necesario, pero en toda clausula "switch" tiene que haber una opción "default:" y no quería dejarla en blanco.
Instalar SubVersion en Ubuntu server 12.04
Una de las herramientas más básicas para todo programador es un controlador de versiones, uno de los más conocidos o como mínimo el único que me he encontrado en mi trabajo diario es el SVN.
Se trata de una herramienta opensource con un gran potencial y muy estable, podéis encontrar muchas más información sobre el en su pagina principal: http://subversion.tigris.org/.
Para instalar el servidor de subversion o SVN como prefiráis, solo tenemos que hacer un par de cosas. Partamos de que estoy utilizando una maquina virtual con el Ubuntu Server 12.04 instalada, prácticamente sin nada más, solo el Xfce que ya le instale en la entrada "Como instalar Xfce en Ubuntu Server 12.04 lts" por si queréis dejar el entorno tal y como yo lo tengo.
Ahora solo tenemos que instalar lo que serian los paquetes básicos del subversion, para ello introduciremos la siguiente linea:
Bien, lo siguiente que tenemos que comprobar es que tenemos instalado los módulos dav y dav_svn y para ello tenemos que introducir los comandos:
a2enmod dav_svn
Si los tenemos instalados tendríamos que ver una pantalla como esta:
Ahora que ya lo hemos instalado volveremos a comprobar si ya funcionan los comandos, personalmente no he detectado ningún error más hasta este punto pero si alguien lo tiene que me lo haga saber e intentare reproducir el error en mi maquina para daros una solución.
Bien, el sistema de control de versiones SVN ya esta instalado en vuestras maquinas, si queréis mirar si la instalación ha sido satisfactoria solo tenéis que escribir:
Como instalar Xfce en Ubuntu Server 12.04 lts
Cuando tienes que virtualizar servicios por la comodidad del transporte te encuentras con la necesidad de no ocupar mucha memoria, lo cual acostumbra a ser un inconveniente en un mundo tan acostumbrado al entorno gráfico ya que este ocupa mucho en memoria, asimismo las versiones "desktop" acostumbran a incorporar mucho software que no hace falta y/o nos distrae de nuestro objetivo.
A la hora de virtualizar sistemas operativos suelo decantarme por Oracle VirtualBox el cual es compatible con Windows, OS X, Solaris y Linux, su gran versatilidad es lo que hace que me decante por el, amén de que es el mejor a mi parecer por su facilidad y robustez.
El sistema operativo que he elegido es el Ubuntu Server 12.04 lts, se que no es el más liviano de todos los que existen, los hay como Tiny core Linux que ocupan solo 11Mb y que serian una perfecta elección para cualquier equipo con pocos recursos o incluso una maquina virtual, pero mi elección se basa en que necesitaba una maquina para usarla como servidor y ya de paso ponerle el SVN, la idea es clara, tener un control de todo el código creado y no perderlo en uno de mis muchos formateo amén de la utilización de varios ordenadores y SO.
Pero Ubuntu Server, como todo buen servidor, no dispone de parte gráfica de manera con la que trabajar, lo que si que dispone es del basto universo de software del que hay en su repositorio, de manera que para instalar el Xfce solo tenemos que seguir estos simples pasos.
- Activar
el repositorio "universe" en caso de que no lo este, para ello
tenemos que comprobar que las siguientes dos lineas existen en el fichero
"/etc/apt/sources.list"
- Actualizar los repositorios
- Instalar los packages necesarios para poner el
sistema grafico
- Durante la instalación es posible que nos
solicite el tamaño de la pantalla, esto ya va a gustos.
- Y ahora para comenzar a utilizarlo solo tenemos
que escribir es “startx”
Ampliar memoria en el WebLogic
Esto es algo que siempre olvido y termino recurriendo a Google para averiguarlo.
Para ampliar la memoria lo primero que tenemos que hacer es localizar desde que directorio se ejecuta. Pensad que el WebLogic no tiene que estar instalado necesariamente en la misma ruta que la ejecución de nuestro proyecto, por ejemplo, mi servidor se encuentra en "c:\ORACLE\Middleware\wls1211\wlserver\server\" mientras que la ejecución de mi proyecto se encuentra en "c:\ORACLE\Middleware\user_projects\domains\Cartera\startWebLogic.cmd" a partir de este fichero nos encontraremos la manera de llegar al fichero "real" de ejecución.
Normalmente este fichero suele tener la siguiente estructura.
@ECHO OFF @REM WARNING: This file is created by the Configuration Wizard. @REM Any changes to this script may be lost when adding extensions to this configuration. SETLOCAL set DOMAIN_HOME=C:\ORACLE\Middleware\user_projects\domains\Cartera call "%DOMAIN_HOME%\bin\startWebLogic.cmd" %* ENDLOCAL
En caso de que usemos Linux tendremos algo parecido a lo siguiente
#!/bin/sh
# WARNING: This file is created by the Configuration Wizard.
# Any changes to this script may be lost when adding extensions to this configuration.
DOMAIN_HOME="C:/ORACLE/Middleware/user_projects/domains/Cartera"
${DOMAIN_HOME}/bin/startWebLogic.sh $*
Si nos fijamos en ambos casos nos redirecciona a la carpeta de instalación. Esto hace que este fichero sea una mera plataforma para arrancar el sistema ya que setea en ambos ficheros la misma dirección.
En el siguiente fichero tenemos el grueso del asunto, el como se va a cargar todo lo que tenemos relacionado con WebLogic. Y lo que no pone es lo que más nos interesa en este momento, hay una variable muy importante que es "MEM_ARGS", esta variable que no esta bien definida en el fichero es la responsable de que podamos ampliar la memoria con la que arrancamos.
Para inicializarla solamente le tenemos que poner la siguiente linea dentro del fichero, indistintamente de que tratemos con el "bat" o el "sh".
set MEM_ARGS=-Xms512m -Xmx1024m -XX:CompileThreshold=8000 -XX:PermSize=64m -XX:MaxPermSize=256m
Y de esta manera nos cargara con la memoria que le indicamos.
AndroidManifest.xml, que es y para que sirve.
<manifest android:versioncode="1" android:versionname="1.0" package="lfr.liem.dazkun.test.android.helloandroid" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minsdkversion="4">
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
<activity android:label="@string/app_name" android:name=".HelloAndroidActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN">
<category android:name="android.intent.category.LAUNCHER">
</category></action></intent-filter>
</activity>
</application>
</uses-sdk></manifest>
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
<activity android:label="@string/app_name" android:name=".HelloAndroidActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN">
<category android:name="android.intent.category.LAUNCHER">
</category></action></intent-filter>
</activity>
</application>
Dentro del AndroidManifest.xml se pueden implementar también permisos, dispositivos y aplicaciones para ello existen los siguientes elementos que se pueden implementar en el AndroidManifest.xml.
- uses-permission: Con este elemento se pueden declarar los permisos que necesitará nuestra aplicación para funcionar correctamente. Para ello podemos encontrar permisos para acceder al GPS del teléfono así como a los datos de localización para realizar las funciones.
- permission: Este elemento declara los permisos que las actividades o servicios necesitan para poder mantener el correcto uso de los datos de la aplicación y ya de paso mantener la lógica de la misma.
- instrumentation: Con este elemento lo que buscaremos es la declaración del código que deberá ser invocado cuando un evento clave del sistema sea llamado por el usuario, tales como el arranque de una actividad como podría ser el logueo o monitoreo.
- application: Esta es la piedra angular de todo nuestro proyecto en el definiremos las entrañas de nuestro programa (nombre, actividad principal, icono, etc.) que el archivo AndroidManifest.xml describe.
<manifest>
<uses-permission>
<permission>
<permission-tree>
<permission-group>
<instrumentation>
<uses-sdk>
<uses-configuration>
<uses-feature>
<supports-screens>
<compatible-screens>
<supports-gl-texture>
<application>
<activity>
<intent-filter>
<action>
<category>
<data>
</data></category></action></intent-filter>
<meta-data>
</meta-data></activity>
<activity-alias>
<intent-filter> . . . </intent-filter>
<meta-data>
</meta-data></activity-alias>
<service>
<intent-filter> . . . </intent-filter>
<meta-data>
</meta-data></service>
<receiver>
<intent-filter> . . . </intent-filter>
<meta-data>
</meta-data></receiver>
<provider>
<grant-uri-permission>
<meta-data>
</meta-data></grant-uri-permission></provider>
<uses-library>
</uses-library></application>
</supports-gl-texture></compatible-screens></supports-screens></uses-feature></uses-configuration></uses-sdk></instrumentation></permission-group></permission-tree></permission></uses-permission></manifest>
Aparte cada uno de los tags puede contener sus propios parámetros e incluso contener algún nivel más, por ejemplo el tag "Action" solo contiene un parámetro, android:name, pero si miramos el tag "Activity" tendriamos todos estos parametros.
<activity android:allowTaskReparenting=["true" | "false"]
android:alwaysRetainTaskState=["true" | "false"]
android:clearTaskOnLaunch=["true" | "false"]
android:configChanges=["mcc", "mnc", "locale",
"touchscreen", "keyboard", "keyboardHidden",
"navigation", "screenLayout", "fontScale", "uiMode",
"orientation", "screenSize", "smallestScreenSize"]
android:enabled=["true" | "false"]
android:excludeFromRecents=["true" | "false"]
android:exported=["true" | "false"]
android:finishOnTaskLaunch=["true" | "false"]
android:hardwareAccelerated=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:launchMode=["multiple" | "singleTop" |
"singleTask" | "singleInstance"]
android:multiprocess=["true" | "false"]
android:name="string"
android:noHistory=["true" | "false"]
android:permission="string"
android:process="string"
android:screenOrientation=["unspecified" | "user" | "behind" |
"landscape" | "portrait" |
"reverseLandscape" | "reversePortrait" |
"sensorLandscape" | "sensorPortrait" |
"sensor" | "fullSensor" | "nosensor"]
android:stateNotNeeded=["true" | "false"]
android:taskAffinity="string"
android:theme="resource or theme"
android:uiOptions=["none" | "splitActionBarWhenNarrow"]
android:windowSoftInputMode=["stateUnspecified",
"stateUnchanged", "stateHidden",
"stateAlwaysHidden", "stateVisible",
"stateAlwaysVisible", "adjustUnspecified",
"adjustResize", "adjustPan"] >
</activity>
Programando Android en Ubuntu 11.10 (II)
Le damos a "Add..." e introducimos con el nombre ADT Plugin y la URL que nos facilita Google, que a día de hoy seria https://dl-ssl.google.com/android/eclipse/
Puede ser que todo falle, como ha sido mi caso y veamos la siguiente pantalla.
Bien ahora que ya tenemos el marketplace instalado reiniciamos y volvemos a empezar con la instalación del "ADT Plugin", ahora sí que sí que nos saldrá la siguiente imagen, la aceptamos como es obvio y seguimos hacia delante.
Bien, una vez lo tengamos si nos vamos a window --> preferences --> Android podemos modificar el directorio desde el que trabajamos. Voy a poner el que hemos puesto en la primera parte para que de esta manera sirva para algo lo que hicimos hace poco más de una semana.
Ahora lo único que nos queda es comprobar que toda la instalación es correcta, para eso lo mejor que tenemos es hacer un "HelloWorld". Para eso nos creamos un nuevo proyecto en File --> New --> Project... seleccionamos el tipo Android --> Android Project tal y como se muestra en la siguiente pantalla.
public class HelloAndroidActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}
Ahora que ya lo tenemos todo bien tenemos que ejecutarlo mediante el boton de "Run As"
Pero como no tenemos configurado ningun dispositivo nos dara un "error" el cual nos derivara a la creación de dispositivos.
Tras un par de ajustes el emulador cargara perfectamente, y de manera automatica tendremos nuestro programa funcionando :)
Programando Android en Ubuntu 11.10 (I)
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:ferramroberto/java
sudo apt-get update
sudo apt-get install sun-java6-jdk sun-java6-plugin
Con esto ya tendremos instalado el JDK, ahora tenemos que activar las alternativas de Java, para ello introduciremos el siguiente comando.
sudo update-alternatives --config java
Tras este comando podremos observar la siguiente imagen. Personalmente me he quedado con el OpenJDK ya que no tengo ningún problema (como mínimo de momento) en desarrollar con el.
tar -xf android-sdk_r12-linux_x86.tgz
android-sdk*/tools/android
Ahora ya lo tenemos todo instalado, lo siguiente seria cargar Eclipse y configurarlo para programar Android, pero como este post me ha quedado muy largo ya si eso lo dejamos para otro momento.



























