Olá pessoal,
Hoje falarei sobre a utilização de JNI em aplicações J2ME. Eventualmente nos deparamos com a necessidade de acessar recursos nativos de celulares e PDA`s, como a câmera e o GPS, e não encontramos API`s java que nos auxiliem nessa tarefa.
Em muitos casos sequer existem essas API`s uma vez que a máquina virtual não as suporta, o que torna o trabalho ainda pior. Para isso existe uma alternativa: a utilização da Java Native Interface ou simplesmente JNI.
A JNI permite que um código escrito em Java interaja com uma biblioteca, por exemplo, escrita em C/C++ ou em outras tantas linguagens de programação. Ainda sobre a JNI, é possível capturar e lançar exceções de uma biblioteca qualquer e tratá-las dentro da aplicação Java. Imaginemos então um caso real onde precisamos desenvolver uma aplicação para Windows Mobile que acesse o GPS do dispositivo. Utilizando a máquina virtual J9 da IBM bastaria realizar os seguintes passos:
1a – Escrever a classe java que carrega a dll e que possui os métodos nativos que servirão como um proxy para chamar os recursos da DLL. Caso a aplicação esteja sendo desenvolvida com a configuração CDC:
System.loadLibrary("GpsDll"); public native double getLongitude(); public native double getLatitude();
1b – Caso a aplicação esteja sendo desenvolvida com a configuração CLDC, basta importar a classe com.ibm.oti.vm.VM, presente na J9, e utilizar o método VM.loadLibrary() ao invés do System.loadLibrary(). Para isso, a classe onde esse método esta declarado precisa estar dentro da pasta ext da J9 (Ex.: \Program Files\J9\MIDP20\lib\jclMidp20\ext) ou o jar contendo essa classe precisa estar especificado no argumento –Xbootclasspath do arquivo que contem o link para executar a aplicação:
VM.loadLibrary("GpsDll"); public native double getLongitude(); public native double getLatitude();
2 – Compilar a classe;
3 – Utilizar a ferramenta javah, disponivel junto com a SDK do java, para gerar o arquivo header do C/C++. (javah –jni br.com.involves.gps.GpsDevice);
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class br_com_involves_gps_GpsDevice */ #ifndef _Included_br_com_involves_gps_GpsDevice #define _Included_br_com_involves_gps_GpsDevice #ifdef __cplusplus extern "C" { #endif /* * Class: br_com_involves_gps_GpsDevice * Method: getLongitude * Signature: ()D */ JNIEXPORT jdouble JNICALL Java_br_com_involves_gps_GpsDevice_getLongitude (JNIEnv *, jclass); /* * Class: br_com_involves_gps_GpsDevice * Method: getLatitude * Signature: ()D */ JNIEXPORT jdouble JNICALL Java_br_com_involves_gps_GpsDevice_getLatitude (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
4 – Em uma IDE C/C++, como por exemplo o visual studio, criar um arquivo .cpp que irá implementar o header;
#include #include #include #include #include #include #include #include #include #include "br_com_involves_gps_GpsDevice.h" JNIEXPORT jdouble JNICALL Java_br_com_involves_gps_GpsDevice_getLatitude (JNIEnv *env, jclass jObject) { HANDLE g_hGPSDevice; g_hGPSDevice = GPSOpenDevice(NULL,NULL,NULL,0); GPS_POSITION gpsPosition; ZeroMemory(&gpsPosition,sizeof(GPS_POSITION)); gpsPosition.dwVersion=GPS_VERSION_1; gpsPosition.dwSize=sizeof(GPS_POSITION); DWORD result=GPSGetPosition(g_hGPSDevice,&gpsPosition,500000,0); double latitude = 0.0; latitude = gpsPosition.dblLatitude; return (jdouble)latitude; } JNIEXPORT jdouble JNICALL Java_br_com_involves_gps_GpsDevice_getLongitude (JNIEnv *env, jclass jObject) { ..... }
5 – Gerar a DLL para a versão do windows mobile em uso;
6 – Adicionar a dll na pasta bin da J9;
Com esses passos é possível acessar recursos nativos sem depender de API`s java para isso. É possível utilizar a JNI tanto com a configuração CDC como CLDC.
Aproveitem os benefícios da JNI e espero que tenha ajudado vocês a compreendê-la um pouco melhor.
Agradecimentos a Rodrigo Veleda.
Um abraço e até a próxima.


Bom post, tenho certeza de que vai ajudar muita gente que precise realizar essa integração, que não é tão instintiva assim!