Integrar Notificaciones Locales en aplicaciones Cordova

Integrar Notificaciones Locales en aplicaciones Cordova

Las Notificaciones Locales permiten a una aplicación informar a sus usuarios de que tienen algo que comunicar. Por ejemplo un recordatorio o un nuevo elemento a la venta, mientras que la aplicación no se está ejecutando en primer plano. Las Notificaciones Locales se consideran la mejor manera por la cual una aplicación puede comunicarse con su usuario, incluso si el usuario no está utilizando activamente la aplicación.

En este tutorial mostramos cómo desencadenar Notificaciones Locales en una aplicación basada en Cordova. Explicamos cómo funciona una Notificación Local, en qué se diferencian de las notificaciones Push, y las API proporcionadas por el Cordova Local-Notification Plugin para activar las Notificaciones Locales. Crearemos una aplicación recordatorio básica para mostrar cómo utilizarla en un proyecto real.

¿Cómo funcionan las Notificaciones Locales?

Las notificaciones locales pueden mostrar un mensaje, reproducir un sonido distintivo, o actualizar una insignia en el icono de la aplicación.

Para mostrar una Notificación Local en una aplicación se necesita programar una Notificación Local mientras se está ejecutando la misma en primer plano.

Las Notificaciones Locales son compatibles con Android, iOS y Windows Phone.

La diferencia entre notificaciones locales y push?

Las dos se muestran de la misma manera, es decir, se componen de un título, un mensaje, un sonido y un numero en el icono insignia.

La diferencia es que las Notificaciones Locales están programadas por la aplicación en sí mientras que las notificaciones Push son generadas por el servidor de la aplicación para el servidor de servicios Push del sistema operativo del móvil. Las Notificaciones Locales pueden activarse sin que el  móvil esté conectado a Internet. Las notificaciones Push solamente se pueden mostrar en un teléfono si está conectado a Internet.

Cordova Local-Notification Plugin

El Cordova Local-Notification Plugin es un complemento Cordova con el que podemos mostrar notificaciones locales en iOS, Android y Windows Phone.

En este tutorial vamos utilizar el plugin para programar notificaciones locales. Vamos a ver las API proporcionadas por el plugin:

 

Comprobar el permiso

Para que una aplicación programe notificaciones locales tiene que tener el permiso del usuario. Para comprobar si la aplicación tiene permiso de utiliza este código:

cordova.plugins.notification.local.hasPermission(function (granted) {
});

El parámetro granted será true si la aplicación tiene permiso para programar notificaciones locales, de lo contrario será false.

 

Solicitar el permiso

Si una aplicación no tiene permiso para programar notificaciones locales, entonces se tiene que solicitar el permiso. Este es el código para solicitar el permiso:

cordova.plugins.notification.local.registerPermission(function (granted) {
});

El parámetro granted será true  si el usuario concede el permiso, de lo contrario false.

 

Programar una notificación

Puedes programar todas las notificaciones que neceistes. Este es el código para hacerlo:

var sound = device.platform == 'Android' ? 'file://sound.mp3' : 'file://beep.caf';
var date = new Date();
 
cordova.plugins.notification.local.schedule({
    id: 1,
    title: "Message Title",
    message: "Message Text",
    at: date,
    sound: sound,
});

La propiedad at tiene que hacer referencia a una Date del objeto constructor. Si pasamos de la hora actual la notificación local se activa al instante.

Para hacer que la notificación se repita ella misma, hay que añadir una propiedad every que indica el intervalo en minutos y una propiedad firstAt  que indica cuándo se activará por primera vez la notificación. A continuación un ejemplo del código:

var sound = device.platform == 'Android' ? 'file://sound.mp3' : 'file://beep.caf';
var date = new Date();
 
cordova.plugins.notification.local.schedule({
    id: 1
    title: "Message Title",
    message: "Message Text",
    firstAt: date,
    every: 25,
    sound: sound,
});

 

Cancelar la Notificación

Para cancelar una notificación pendiente se necesita el identificador único de la notificación. He aquí un ejemplo:

cordova.plugins.notification.local.cancel(1, function () {
    // Notification was cancelled
}, scope);

 

Hacer clic en la Notificación

Este plugin activa un evento cuando el usuario abre la aplicación haciendo clic en la misma. He aquí un ejemplo del código:

cordova.plugins.notification.local.on("click", function (notification) {
    alert(notification.text);
}, scope);

 

Creación de un App de Recordatorio

Vamos a empezar con la realización de una aplicación de recordatorio. La aplicación de recordatorio permitirá agregar recordatorios para una fecha y hora específicos. El recordatorio desencadenará una notificación local programada por la aplicación para ese momento.

La aplicación la diseñamos utilizando jQuery móvil.

 

En primer lugar

En la plantilla de inicio, incluir jQuery y jQuery móvil. No vamos a mostrar aquí como hacer la instalación y la creación de una aplicación Cordova, si lo necesitas puedes leer aquí la guía de instalación inicial. Las instrucciones para ejecutar y construir la aplicación están disponibles en la misma página.

Hay que dar a la aplicación un nombre apropiado y añadir las plataformas que desea soportar. Utilizamos el Cordova’s Notification plugin y el Device plugin en este tutorial, puedes encontrar instrucciones sobre cómo agregarlos aquí .

Como vamos a utilizar el plugin local de notificación.

Dentro del archivo www/index.html, agrega los siguientes archivos JavaScript y CSS a la etiqueta head:

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

Hemos añadido jQuery y jQuery Mobile desde CDN. Puedes incrustar estos archivos localmente para que la aplicación funcione sin conexión a Internet.

 

Estructura de datos

En este tutorial vamos a utilizar el almacenamiento local de HTML5 para almacenar los datos de la aplicación.

Vamos organizar todos los datos en una matriz que será una propiedad de un objeto. El objeto se almacena como una cadena JSON en el almacenamiento local.

Cuando se carga la aplicación por primera vez, el almacenamiento local estará vacío, por lo que la estructura de datos  se tiene que iniciar. Por debajo el código chequea el objeto en el almacenamiento local. Como está vacío se crea y almacena uno nuevo. Coloca este código en una etiqueta del script en la parte inferior de la página index.html, antes del cierre de la etiqueta body:

var info = null;
 
document.addEventListener("deviceready", function(){
if(!localStorage.getItem("rp_data"))
{
  var rp_data = {data: []};
  localStorage.setItem("rp_data", JSON.stringify(rp_data));
}
 
info = JSON.parse(localStorage.getItem("rp_data"));
}, false);

Aquí hemos creado una variable info utilizada en toda la aplicación para acceder a los datos. Siempre que haga cambios en la variable info necesito actualizar el almacenamiento local.

 

Creación de la pantalla de inicio

Vamos a crear la pantalla de inicio de nuestra aplicación que se mostrará cuando se carga la aplicación.

En la pantalla de inicio pondremos tres botones. Son para añadir un nuevo recordatorio, mostrar todos los recordatorios y mostrar los recordatorios pendientes.

Este es el código para crear una página jQuery móvil para nuestra pantalla de inicio. Coloca este código en la etiqueta body de la página index.html:

<div data-role="page" id="home">
  <div data-role="header">
    <h1>Reminder App</h1>
  </div>
 
  <div data-role="main" class="ui-content">
    <p>
        <a target="_blank" href="#add" style="text-decoration: none"><button>Add Reminder</button></a>
        <a target="_blank" id="pending_click" href="#pending" style="text-decoration: none"><button>Pending Reminders</button></a>
        <a target="_blank" href="#all" style="text-decoration: none"><button>All Reminders</button></a>
    </p>
  </div>
</div>

Nota:  Si hay que añadir código para otras páginas hacerlo debajo de este código, esta página se carga primero.

 

Creación de una página para agregar el Recordatorio

Cuando un usuario hace clic en el botón Add reminder en la página de inicio aparece una nueva página donde el usuario puede añadir un nuevo recordatorio.

A continuación muestra cuatro cuadros de texto (título, mensaje, fecha y hora) y un botón para agregar un recordatorio. Coloca el código en la etiqueta body del archivo index.html:

<div data-role="page" id="add">
  <div data-role="header">
    <a target="_blank" href="#home" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
    <h1>Add Reminder</h1>
  </div>
 
  <div data-role="main" class="ui-content">
    <p>
        Enter title and message for the reminder:
        <input type="text" id="title" placeholder="Title" />
        <input type="text" id="message" placeholder="Message" />
        Enter date and time to trigger reminder:
        <input type="date" id="date" />
        <input type="time" id="time" />
        <a target="_blank" href="javascript:add_reminder()" style="text-decoration: none"><button>Add</button></a>
    </p>
  </div>
</div>

Cuando el usuario hace clic en el botón Agregar se produce una llamada a la función add_reminder (). Aquí está la implementación de esta función, agrega este código a la etiqueta script del archivo index.html:

function add_reminder()
{
    var date = document.getElementById("date").value;
    var time = document.getElementById("time").value;
    var title = document.getElementById("title").value;
    var message = document.getElementById("message").value;
 
    if(date == "" || time == "" || title == "" || message == "")
    {
      navigator.notification.alert("Please enter all details");
      return;
    }
 
    var schedule_time = new Date((date + " " + time).replace(/-/g, "/")).getTime();
    schedule_time = new Date(schedule_time);
 
    var id = info.data.length;
 
    cordova.plugins.notification.local.hasPermission(function(granted){
      if(granted == true)
      {
        schedule(id, title, message, schedule_time);
      }
      else
      {
        cordova.plugins.notification.local.registerPermission(function(granted) {
            if(granted == true)
            {
              schedule(id, title, message, schedule_time);
            }
            else
            {
              navigator.notification.alert("Reminder cannot be added because app doesn't have permission");
            }
        });
      }
    });
}

En primer lugar estamos recuperando los valores de los campos y comprobando su integridad. Luego formateamos la fecha y la hora para conseguir una cadena con el formato adecuado para su uso en el constructor Date.

Entonces la aplicación chequea si tiene los permisos correctos. Si no es así, entonces pide permiso e invoca la función schedule que programa un recordatorio.

Aquí está la implementación de la función schedule:

function schedule(id, title, message, schedule_time)
{
    cordova.plugins.notification.local.schedule({
        id: id,
        title: title,
        message: message,
        at: schedule_time
    });
 
    var array = [id, title, message, schedule_time];
    info.data[info.data.length] = array;
    localStorage.setItem("rp_data", JSON.stringify(info));
 
    navigator.notification.alert("Reminder added successfully")
}

La función Schedule programa una notificación local y almacena los detalles del recordatorio en el almacenamiento local para futuras consultas.



Viendo todos los recordatorios

Cuando un usuario hace clic en el botón Todos los Recordatorios en la página de inicio se visualiza una nueva página con todos los recordatorios agregados.

Coloca este código en la etiqueta body del archivo index.html:

<div data-role="page" id="all">
  <div data-role="header">
    <a target="_blank" href="#home" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
    <h1>All Reminders</h1>
  </div>
 
  <div data-role="main" class="ui-content">
    <table data-role="table" data-mode="column" id="allTable" class="ui-responsive table-stroke">
      <thead>
        <tr>
          <th>Title</th>
          <th>Time</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </div>
</div>

Aquí está el código JavaScript para rellenar la tabla con todos los recordatorios. Coloca este código en la etiqueta script:

$(document).on("pagebeforeshow","#all",function(){
 
    var html = '';
 
    for(var count = 0; count < info.data.length; count++)
    {
        html = html + "<tr><td>" + info.data[count][1] + "</td><td>" + info.data[count][3] + "</td></tr>";
 
    }
 
    $("table#allTable tbody").empty();
    $("table#allTable tbody").append(html).closest("table#allTable").table("refresh").trigger("create"); 
});

 

Viendo los Recordatorios pendientes

Cuando un usuario hace clic en el botón de los Recordatorios pendientes en la página de inicio aparece una nueva página con los recordatorios pendientes.

Coloca este código en la etiqueta body del archivo index.html para mostrar esta página:

<div data-role="page" id="pending">
  <div data-role="header">
    <a target="_blank" href="#home" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
    <h1>Pending</h1>
  </div>
 
  <div data-role="main" class="ui-content">
    <table data-role="table" data-mode="column" id="pendingTable" class="ui-responsive table-stroke">
      <thead>
        <tr>
          <th>Title</th>
          <th>Time</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  </div>
</div>

Aquí está el código JavaScript para rellenar la tabla con los recordatorios pendientes. Coloca este código en la etiqueta script:

$(document).on("pagebeforeshow","#pending",function(){
 
    var html = '';
 
    for(var count = 0; count < info.data.length; count++)
    {
        var schedule_time = new Date(info.data[count][3]).getTime();
        var current_time = new Date().getTime();
 
        if(current_time < schedule_time)
        {
          html = html + "<tr><td>" + info.data[count][1] + "</td><td>" + info.data[count][3] + "</td></tr>";
        }
    }
 
    $("table#pendingTable tbody").empty();
    $("table#pendingTable tbody").append(html).closest("table#pendingTable").table("refresh").trigger("create"); 
});

Comentarios

Comentario de Nestor Bogantes - 08 de Abril de 2018 - 00:53
Este código está genial, sólo que no sé a que se refieren cuando dicen "agrega este código a la etiqueta script del archivo index.html:" Tengo que crear la etiqueta o lo ingreso en un script del index... no comprendo, soy muy nuevo en esto. Disculpen mi ignorancia y por favor ayudenme. Gracias
Ha habido un error en el envío
Comentario enviado. Será revisado por la moderación antes de ser publicado.

Deja tu comentario

Tu nombre:
Tu email:
Tu comentario: