Integración nativa con html5

40
INTEGRACIÓN NATIVA CON HTML5 JOSÉ ROBERTO ARDILA GARCÍA 12 HIT COMBO!

description

Integración nativa con html5. José Roberto ardila García 12 hit combo!. Porque es necesaria la integración nativa?. Hagamos un repaso de las características que nos ofrece PhoneGap Acelerómetro Cámara Brújula Acceso a contactos Archivos Geolocalización Media Network - PowerPoint PPT Presentation

Transcript of Integración nativa con html5

Page 1: Integración nativa con html5

INTEGRACIÓN NATIVA CON HTML5

JOSÉ ROBERTO ARDILA GARCÍA

12 HIT COMBO!

Page 2: Integración nativa con html5

PORQUE ES NECESARIA LA INTEGRACIÓN NATIVA?• HAGAMOS UN REPASO DE LAS CARACTERÍSTICAS QUE NOS OFRECE PHONEGAP

• ACELERÓMETRO

• CÁMARA

• BRÚJULA

• ACCESO A CONTACTOS

• ARCHIVOS

• GEOLOCALIZACIÓN

• MEDIA

• NETWORK

• NOTIFICACIONES (ALERTAS, SONIDOS, VIBRACIONES).

Page 3: Integración nativa con html5

PERO QUE OCURRE SI SE NECESITA O APARECE UNA NUEVA CARACTERÍSTICA NUEVA O DIFERENTE EN LOS DISPOSITIVOS ANDROID?

• NFC

• IBEACONS (COMUNICACIÓN VÍA BLUETOOTH)

• WIDGETS

• TEXTTOSPEECH

• VOICETYPING

• REUTILIZAR CÓDIGO O ACTIVITIES QUE REALIZABAN OPERACIONES ESPECÍFICAS Y PUNTUALES (POR EJEMPLO ENVIAR CORREOS)…

Page 4: Integración nativa con html5

QUE OCURRE SI PHONEGAP NO OFRECE SOPORTE PARA ELLO….

• LLORAR?

• ESPERAR A QUE EN ALGÚN MOMENTO PHONEGAP OFREZCA SOPORTE PARA ESAS CARACTERÍSTICAS?

• ENSUCIARSE LAS MANOS Y EXTENDER DE ALGUNA FORMA LA FUNCIONALIDAD DE PHONEGAP PARA DAR SOPORTE A LAS CARACTERÍSTICAS DESEADAS…

Page 5: Integración nativa con html5

PHONEGAP PLUGINS

• POR MEDIO DE LOS “PLUGINS” ES POSIBLE EXTENDER LAS FUNCIONALIDADES DE PHONEGAP.

• A TRAVÉS DE LOS PLUGINS ES POSIBLE ACCEDER A CARACTERÍSTICAS NATIVAS DE LOS DISPOSITIVOS

• PHONEGAP UTILIZA ESE CONCEPTO PARA ACCEDER A LAS CARACTERÍSTICAS NATIVAS PREVIAMENTE MENCIONADAS.

• LOS PLUGINS SON DESARROLLADOS EN CÓDIGO NATIVO DE LA PLATAFORMA (EN EL CASO DE ANDROID: JAVA)

Page 6: Integración nativa con html5

ENTENDIENDO LA ESTRUCTURA DE PLUGINS NATIVOS DE PHONEGAP

• LOS PLUGIN TIENEN 2 PARTES: UNA INTERFAZ BASADA EN JAVASCRIPT QUE PUEDE ACCEDERSE DESDE LA APLICACIÓN PHONEGAP (Y QUE SERÁ UTILIZADA EN TODAS LAS PLATAFORMAS) Y SU CORRESPONDIENTE CLASE NATIVA QUE REALIZARÁ LAS OPERACIONES NECESARIAS EN CÓDIGO NATIVO.

• LA INTERFAZ EN JAVASCRIPT INVOCARÁ AL CÓDIGO NATIVO UTILIZANDO EL MÉTODO CORDOVA.EXEC, EL CUAL INVOCARÁ A UN MÉTODO EXECUTE PRESENTE EN LAS CLASES NATIVAS.

Page 7: Integración nativa con html5

ENTENDIENDO LA ESTRUCTURA DE PLUGINS NATIVOS DE PHONEGAP

Page 8: Integración nativa con html5

EL MÉTODO CORDOVA.EXEC

• CORDOVA.EXEC(SUCCESSCALLBACK, FAILURECALLBACK, CLASS, METHOD, [ARGUMENTS]); 

• SUCCESSCALLBACK: SERÁ LA FUNCIÓN QUE SE QUIERA EJECUTAR CUANDO EL RESULTADO DE LA INVOCACIÓN SEA SATISFACTORIO.

• FAILURECALLBACK: SERÁ LA FUNCIÓN A EJECUTAR CUANDO EL RESULTADO DE LA INVOCACIÓN NO SEA SATISFACTORIO.

Page 9: Integración nativa con html5

EL MÉTODO CORDOVA.EXEC

• CORDOVA.EXEC(SUCCESSCALLBACK, FAILURECALLBACK, CLASS, METHOD, [ARGUMENTS]);

• CLASS: SERÁ EL NOMBRE DE LA CLASE DE NUESTRO CÓDIGO NATIVO.

• METHOD: SERÁ EL NOMBRE DE LA ACCIÓN QUE SE VA A TENER EN CUENTA EN EL MÉTODO "EXECUTE" DE LA CLASE ANTERIOR QUE QUEREMOS INVOCAR.

• [ARGUMENTS]]: SERÁ UN ARRAY, GENERALMENTE EN FORMATO JSON, DONDE SE LE PASAN TODOS LOS PARÁMETROS DE ENTRADA AL MÉTODO INVOCADO.

Page 10: Integración nativa con html5

CREACIÓN DE NUESTRO PRIMER PLUGIN

1. CREAMOS UN NUEVO PROYECTO PHONEGAP (OFFLINE) Y LO IMPORTAMOS A ECLIPSE:

$ cordova create C:\MyFirstPlugin com.unal.plugins CustomPluginActivity$cd C:\MyFirstPlugin $cordova platform add android

Page 11: Integración nativa con html5

CREACIÓN DE NUESTRA CLASE NATIVA

• CREAMOS UNA NUEVA CLASE “HELLOPLUGIN” QUE EXTIENDA DE ORG.APACHE.CORDOVA.CORDOVAPLUGIN

• EN ESTA CLASE IRÁN LAS OPERACIONES NATIVAS QUE NECESITEMOS EJECUTAR

Page 12: Integración nativa con html5

public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {

boolean validAction = true;Log.d("Plugin ejecutando acción:",action);if (action.equals("nativeAction")) {

callbackContext.success(args.getString(0));}else {

validAction = false;}return validAction;

}

Page 13: Integración nativa con html5

REGISTRAR EL NUEVO PLUGIN:

• EN NUESTRO ARCHIVO RES/XML/CONFIG.XML REGISTRAMOS NUESTRO NUEVO PLUGIN, DENTRO DE LOS TAGS “WIDGET”.

<feature name="HelloPlugin"> <param name="android-package" value="com.unal.plugins.plugin.HelloPlugin" /> </feature>

Page 14: Integración nativa con html5

• MODIFICAMOS NUESTRO INDEX.XML PARA USAR NUESTRO NUEVO PLUGIN:

<!DOCTYPE html><html> <head> <title>Hola Plugin</title> </head> <body>

<h1>Prueba del nuevo Plugin!</h1>

<button onclick="callNativePlugin('success');">Click para invocar al PluginNativo con SUCCESS!</button> <button onclick="callNativePlugin('error');">Click para invocar al PluginNativo con ERROR!</button> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/HelloPlugin.js"></script> </body></html>

Page 15: Integración nativa con html5

Y DE LOS CALLBACKS CORRESPONDIENTES…

function callNativePlugin( returnSuccess ) { HelloPlugin.callNativeFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess ); }

function nativePluginResultHandler (result){ alert("SUCCESS: \r\n"+result ); } function nativePluginErrorHandler (error){ alert("ERROR: \r\n"+error ); }

Page 16: Integración nativa con html5

CREAMOS NUESTRO ARCHIVO HELLOPLUGIN.JS ENCARGADO DE CONTENER LOS MÉTODOS DE EJECUCIÓN DEL PLUGIN NATIVO….

var HelloPlugin = { callNativeFunction: function (success, fail, resultType) { return cordova.exec( success, fail, "HelloPlugin", "nativeAction", [resultType]); } };

Page 17: Integración nativa con html5
Page 18: Integración nativa con html5

CREACIÓN DE UNA NUEVA CLASE NATIVAPARA INVOCAR UNA AGENDA NATIVA

• CREAMOS UNA NUEVA CLASE “CALENDARPLUGIN” QUE EXTIENDA DE ORG.APACHE.CORDOVA.CORDOVAPLUGIN

• EN ESTA CLASE IRÁN LAS OPERACIONES NATIVAS QUE NECESITEMOS EJECUTAR

Page 19: Integración nativa con html5

public class CalendarPlugin extends CordovaPlugin {

public static final String ACTION_ADD_CALENDAR_ENTRY = "addCalendarEntry";

@Overridepublic boolean execute(String action, JSONArray args, CallbackContext

callbackContext) throws JSONException {

try { if (ACTION_ADD_CALENDAR_ENTRY.equals(action)) {

Page 20: Integración nativa con html5

CREACIÓN DEL CALENDAR NATIVO (CON LOS PARÁMETROS TRAÍDOS DESDE PHONEGAP)

• YA QUE ESTAMOS TRABAJANDO DE FORMA NATIVA PODEMOS INVOCAR UN ACTIVITY EXTERNO DE LA MISMA FORMA QUE HARÍAMOS NORMALMENTE.

• UTILIZAMOS UN INTENT INTENT.ACTION_EDIT PARA CREAR LA AGENDA.

• LOS PARÁMETROS QUE NECESITAMOS PARA CREAR LA AGENDA SERÁN DATOS TRAÍDOS DESDE PHONEGAP.

• ESTOS PARÁMETROS VENDRÁN EN FORMATO JSON.

Page 21: Integración nativa con html5

JSONObject arg_object = args.getJSONObject(0);

Intent calIntent = new Intent(Intent.ACTION_EDIT) .setType("vnd.android.cursor.item/event") .putExtra("beginTime",

arg_object.getLong("startTimeMillis")) .putExtra("endTime", arg_object.getLong("endTimeMillis")) .putExtra("title", arg_object.getString("title")) .putExtra("description",

arg_object.getString("description")) .putExtra("eventLocation",

arg_object.getString("eventLocation")); this.cordova.getActivity().startActivity(calIntent); callbackContext.success(); return true;

Page 22: Integración nativa con html5

} callbackContext.error("Invalid action"); return false;} catch(Exception e) { System.err.println("Exception: " + e.getMessage()); callbackContext.error(e.getMessage()); return false;}

}

Page 23: Integración nativa con html5

• PODEMOS AGREGAR MÚLTIPLES PLUGINS NATIVOS A UNA MISMA APLICACIÓN

<feature name="HelloPlugin"> <param name="android-package" value="com.unal.plugins.plugin.HelloPlugin" />

</feature>

<feature name="CalendarPlugin"> <param name="android-package" value="com.unal.plugins.plugin.CalendarPlugin" /></feature>

Page 24: Integración nativa con html5

CREAMOS UN ARCHIVO LLAMADO CALENDARPLUGIN.JS Y UNA FUNCIÓN CREATEEVENT:

var calendarPlugin = { createEvent: function(title, location, notes, startDate, endDate, successCallback, errorCallback) { cordova.exec( successCallback, errorCallback, 'CalendarPlugin', 'addCalendarEntry',

[{"title": title,

"description": notes, "eventLocation": location, "startTimeMillis": startDate.getTime(), "endTimeMillis": endDate.getTime() }] ); }}

Page 25: Integración nativa con html5

• CON ESTE MÉTODO ES QUE INICIALIZAMOS LOS DATOS DE NUESTRA AGENDA (ESTE CÓDIGO TAMBIÉN VA EN EL ARCHIVO CALENDARPLUGIN.JS)

function addToCal() { var startDate = new Date("July 19, 2013 8:00:00"); var endDate = new Date("July 19, 2013 18:00:00"); var notes = “llegar a tiempo al evento(desde Android)"; var title = "PhoneGap Day"; var location = "Portland, OR"; var notes = “llegar a tiempo!"; var success = function() { alert(“exito"); }; var error = function(message) { alert(“error! " + message); }; calendarPlugin.createEvent(title, location, notes, startDate, endDate, success, error);}

Page 26: Integración nativa con html5

• PODEMOS AGREGAR A NUESTRA PÁGINA YA EXISTENTE EL NUEVO PLUGIN…

<!DOCTYPE html><html> <head> <title>Hola Plugin</title> </head> <body> <h1>Prueba del nuevo Plugin!</h1>

<button onclick="callNativePlugin('success');">Click para invocar al PluginNativo con SUCCESS!</button>

<button onclick="callNativePlugin('error');">Click para invocar al PluginNativo con ERROR!</button>

<button onclick="addToCal();">Click para crear una agenda </button>

<script type="text/javascript" src="js/CalendarPlugin.js"></script>

<script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/HelloPlugin.js"></script>

</body></html>

Page 27: Integración nativa con html5

AGREGAR TEXT TO SPEECH

• CREAMOS UNA NUEVA CLASE “TTSPLUGIN” QUE EXTIENDA DE ORG.APACHE.CORDOVA.CORDOVAPLUGIN

• EN ESTA CLASE IRÁN LAS OPERACIONES NATIVAS QUE NECESITEMOS EJECUTAR

• ESTE ES UN EJEMPLO DE COMO UTILIZAR DATOS QUE SE RECIBEN DESDE PHONEGAP.

Page 28: Integración nativa con html5

• EN ESTA OCASIÓN UTILIZAREMOS 2 ACCIONES UNA PARA INICIAR EL SISTEMA TTS Y OTRO PARA EJECUTAR LA ACCIÓN DE CONVERSIÓN DE TEXTO A SONIDO, DE AHÍ QUE DECLARAREMOS LAS SIGUIENTES VARIABLES GLOBALES:

public static final String ACTION_NEW_TTS_INIT = "textToSpeechInit"; public static final String ACTION_NEW_TTS_TALK = "textToSpeechTalk";TextToSpeech ttobj;

Page 29: Integración nativa con html5

@Overridepublic boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {

• DEBIDO A QUE LAS OPERACIONES TTS SON BASTANTE EXIGENTE DEBEMOS UTILIZAR MULTI-THREADING, ESTO NOS OBLIGA A QUE ALGUNOS PARÁMETROS TENGAN QUE SER DECLARADAS COMO FINAL:

Page 30: Integración nativa con html5

if (ACTION_NEW_TTS_INIT.equals(action)) { cordova.getThreadPool().execute(new Runnable() { public void run() {

if(ttobj == null) {

ttobj=new TextToSpeech(cordova.getActivity().getApplicationContext(), new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if(status != TextToSpeech.ERROR){ ttobj.setLanguage(Locale.US); } } });

} } }); return true;}

Page 31: Integración nativa con html5

else if(ACTION_NEW_TTS_TALK.equals(action)){ cordova.getThreadPool().execute(new Runnable() { public void run() { try { ttobj.speak(args.getString(0), TextToSpeech.QUEUE_FLUSH, null); callbackContext.success(); } catch(Exception e) { callbackContext.error(e.getMessage()); } } }); return true;}else{ return false;}

Page 32: Integración nativa con html5

• AGREGAMOS NUESTRO PLUGIN (EN RES/XML/CONFIG.XML)

• Y CREAMOS UN NUEVO ARCHIVO JAVASCRIPT LLAMADO TTSPLUGIN.JS

<feature name="TTSPlugin"> <param name="android-package" value="com.unal.plugins.plugin.TTSPlugin" /></feature>

var TTSPlugin = { callTTSInitFunction: function (success, fail, resultType) { return cordova.exec( success, fail, "TTSPlugin", "textToSpeechInit", [resultType]); },

callTTSTalkFunction: function (success, fail, resultType) { return cordova.exec( success, fail, "TTSPlugin", "textToSpeechTalk", [resultType]); } };

Page 33: Integración nativa con html5

• AGREGAMOS LAS FUNCIONES DE CALLBACK Y LAS QUE LLAMAREMOS DE NUESTRO CÓDIGO:

function callTTSInitPlugin(returnSuccess) { TTSPlugin.callTTSInitFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess ); }

function callTTSTalkPlugin( returnSuccess ) { TTSPlugin.callTTSTalkFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess ); } function nativePluginResultHandler (result) { alert("SUCCESS: \r\n"+result ); }

function nativePluginErrorHandler (error) { alert("ERROR: \r\n"+error ); }

Page 34: Integración nativa con html5

• MODIFICAMOS NUESTRO ARCHIVO INDEX.JS PARA QUE QUEDE ASÍ (DE ESTA FORMA INICIALIZAMOS EL SISTEMA TTS AL CARGAR LA PÁGINA):

var app = {

// Application Constructor initialize: function() {

this.bindEvents(); },

bindEvents: function() {

document.addEventListener('deviceready', this.onDeviceReady, false); },onDeviceReady: function() {

callTTSInitPlugin('inicia'); },

};

Page 35: Integración nativa con html5

• PARA FACILITAR LA MANIPULACIÓN DE DATOS, UTILIZAREMOS JQUERY, PARA ESTO DESCARGAREMOS EL ARCHIVO JAVASCRIPT DE JQUERY DESDE:

• HTTP://JQUERY.COM/DOWNLOAD/

• Y LO COPIAREMOS EN NUESTRA CARPETA ASSETS/WWW/JS

Page 36: Integración nativa con html5

<div id="landmark-1" onsubmit="callTTSTalkPlugin($('#title').val());"><form><label for="title">TTS:</label><input id="title" name="title" type="text" />

<input type="submit" value="Click para TTS"></form></div>

<script type="text/javascript" src="js/index.js"></script> <script type="text/javascript" src="js/TTSPlugin.js"></script> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript"> app.initialize();

</script>

• AGREGAREMOS A NUESTRO ARCHIVO INDEX.HTML LO SIGUIENTE:

Page 37: Integración nativa con html5
Page 38: Integración nativa con html5

AGREGAR TEXT TO SPEECH

• CREAMOS UNA NUEVA CLASE “STTPLUGIN” QUE EXTIENDA DE ORG.APACHE.CORDOVA.CORDOVAPLUGIN

• EN ESTA CLASE IRÁN LAS OPERACIONES NATIVAS QUE NECESITEMOS EJECUTAR

• ESTE ES UN EJEMPLO DE COMO UTILIZAR DATOS QUE SE RECIBEN DESDE PHONEGAP.

Page 39: Integración nativa con html5

public static final String ACTION_NEW_STT_TALK = "SpeechToTextTalk";CallbackContext callbackContext;protected static final int RESULT_SPEECH = 1;

@Overridepublic boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

this.callbackContext = callbackContext; if(ACTION_NEW_STT_TALK.equals(action)) {

Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US"); this.cordova.getActivity().startActivityForResult(intent, RESULT_SPEECH); return true;

} else { return false; }}

Page 40: Integración nativa con html5

public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case RESULT_SPEECH: if (resultCode == android.app.Activity.RESULT_OK && null != data) { ArrayList<String> text = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); callbackContext.success(text.get(0)); } else { //code launched in case of error String message=data.getStringExtra("result"); callbackContext.error(message); } break; default: break; }}