Cómo listar tu aplicación de cordova en el menú "abrir con" en menú de Android y manipular el evento "intent"

Cómo listar tu aplicación de cordova en el menú "abrir con" en menú de Android y manipular el evento "intent"

Android Open With

Si quieres que tu aplicación aparezca en el listado de aplicaciones especificas para abrir cierto tipo de archivos, necesitarás solicitar este permiso desde el manifiesto de Android (AndroidManifest.xml) en tu aplicación:

Requisitos

Para lograr esta tarea, necesitarás 2 plugins especificos como dependencia en tu aplicación:

  1. cordova-custom-config : Necesitas cambiar la configuración predeterminada del manifiesto de Android, sin embargo no lo manipularas manualmente pues los cambios que hagas al archivo pueden perderse en compilaciones futuras, por lo tanto necesitas usar este plugin que te permitira agregar propiedades personalizadas cada vez que compilas.
  2. cordova-plugin-intent : Cuando la configuración de las propiedades personalizadas en el manifiesto esten listas, necesitarás de alguna manera obtener la información enviada por el sistema operativo cuando tu aplicación es seleccionada en la lista de "abrir con" (recuerda que estos eventos deben responder de manera diferente cuando tu aplicación ya esta abierta o no).
  3. Paciencia !

Antes de continuar

Antes de continuar, necesitas saber que es lo que vamos a hacer y porque. Necesitarás modificar el tag intent-filter y agregar un par de permisos (que en este ejemplo, la aplicación abrira todo tipo de archivos, puedes leer más sobre los mimetypes de android aquí para filtrar por las extensiones que requieras).

Así que en la plataforma android, bastaría con colocar el siguiente bloque en el manifiesto:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="file" />
    <data android:mimeType="*/*" />
    <data android:pathPattern=".*\\.txt" />
</intent-filter>

Sin embargo, el problema es que no podemos simplemente agregar el bloque previo a nuestro config.xml pues este no será reconocido, allí es cuando entra el plugin cordova-custom-config al juego, que nos ayudará directamente a modificar el manifiesto de android (AndroidManifest.xml). Finalmente usaremos el plugin de cordova-plugin-intent para manipular los eventos cuando tu app es seleccionada de la lista usando javascript.

Descarga los plugins y permite el uso de Intent en tu aplicación

Un "Intent" es un objeto de mensaje que puedes usar para solicitar una acción desde un componente de otra app. Para comenzar, agrega los plugins a tu aplicación ejecutando:

# Instalar configuración personalizada
$ cordova plugin add cordova-custom-config
# Luego instala el plugin que nos ayudara a manipular los intentos
$ cordova plugin add https://github.com/napolitano/cordova-plugin-intent

Luego necesitas permitir el uso de la configuración personalizada en tu proyecto, para ello agrega la siguiente propiedad al nodo "widget" en tu archivo config.xml xmlns:android="http://schemas.android.com/apk/res/android"

Así tu archivo lucirá similar a:

<?xml version='1.0' encoding='utf-8'?>
<!-- Nota la propiedad xmlns:android="blabla" en el nodo -->
<widget id="com.ourcodeworld.ourcodeeditorfree" version="1.3.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Haremos algunos cambios en este bloque mas tarde -->
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

Ahora modifica de nuevo el archivo config.xml y agrega el bloque intent-filter usando un bloque de configuración (el plugin custom-config va a agregar todo el contenido directamente al manifiesto de android sin remove bloques existentes):

Debes saber que necesitas crear un bloque extra de intent-filter en el manifiesto, de otra manera si agregas estas propiedades a un intent-filter existente, tu aplicación será compilada, sin embargo no podrás ver el icono para iniciar tu aplicación más tarde.

<!-- Localiza el bloque de android en tu config.xml -->
<platform name="android">
        <!--
            Agrega un nuevo intent-filter a la actividad de tu app
        -->
        <config-file target="AndroidManifest.xml" parent="./application/activity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.txt" />
            </intent-filter>
        </config-file>
</platform>

Si decides compilar ya tu aplicación, el archivo AndroidManifest.xml debería tener ya incluido las propiedades dentro de un nuevo bloque de intent-filter:

Intent filter open with menu settings

Y si abres el menú de "abrir con" (desde cualquier aplicación) y el mimeType del archivo coincide con el declarado anteriormente, tu aplicación debería aparecer en la lista ahora. Sin embargo aun necesitas aprender como los archivos (o su información) serán manipulados con Javascript.

Manipular intentos

Aquí cordova-plugin-intent nos ayudará. Necesitas hacer algo con los archivos (la información del archivo) que recibiras y manipularas usando el siguiente código (despues del evento onDeviceReady):

document.addEventListener('deviceready', function(){
    var HandleIntent = function (Intent) {
        console.log(intent);       

        if(Intent.hasOwnProperty('data')){
            // Hacer algo con el archivo
        }else{
            // Este bloque ocurrirá cuando la aplicación inicia y no hay un intento activo
            console.log("La app fue abierta manualmente y no hay archivo (info) enviada");
        }
    };

    // Manipula el intento cuando la aplicación ya está abierta
    // es decir, si la app esta siendo ejecutada en el fondo, este callback será ejecutado
    window.plugins.intent.setNewIntentHandler(HandleIntent);

    // Manipula el intento cuando la app no está abierta
    // este callback será ejecutado solo cuando la app inicia o no estába activa en el fondo
    window.plugins.intent.getCordovaIntent(HandleIntent, function () {
        alert("Error: no se pudo manipular el intento");
    });
}, false);

La estructura de un objeto intento es similar a:

{
    "action": "android.intent.action.SEND_MULTIPLE",
    "clipItems": [
        {
            "uri": "file:///storage/emulated/0/Download/example-document.pdf",
            "type": "application/pdf",
            "extension": "pdf"
        },
        {
            "uri": "file:///storage/emulated/0/Download/example-archive.zip",
            "type": "application/zip",
            "extension": "zip"
        }
        {
            "uri": "content://media/external/images/media/29",
            "type": "image/jpeg",
            "extension": "jpeg"
        }

    ],
    "flags": 390070273,
    "type": "*/*",
    "component": "ComponentInfo{com.example.droid/com.example.droid.MainActivity}",
    "extras": "Bundle[mParcelledData.dataSize=596]"
}

Lee mas acerca de este plugin (cordova intent) en el repositorio oficial de Github aquí

Ahora compila tu aplicación y verás tu aplicación en la lista de "abrir con" y serás capaz de hacer algo con la información recibida del archivo.

Test

Que te diviertas !

Esto podría ser de tu interes

Conviertete en un programador más sociable