Ejemplo sencillo de notificaciones (toast) para Windows Store

 

Pues eso… que aunque aún no son horas de toastar nada, pero te voy a poner un par de ejemplos (o uno solo) de cómo mostrar las notificaciones del sistema (toast notifications), que no son otra cosa que los mensajes (o notificaciones) que aparecen en los laterales de la parte superior de la pantalla de Windows (ver la figura 1).

 

toast01
Figura 1.

 

En principio este tipo de notificaciones están pensadas para eso, notificar al usuario de algo en un momento concreto (ahora te explico esto), pero sobre todo, que el usuario se entere de que eso está ocurriendo (lo están avisando), así que… este tipo de notificaciones se mostrarán siempre encima de lo que haya en ese momento en la pantalla… y cuando digo pantalla me refiero a la pantalla tanto de inicio de Windows 8 como a la "pantalla del escritorio".

 

Lo del par de ejemplos que te comentaba antes es porque hay dos formas de notificar (o mostrar las notificaciones). Una es de forma inmediata, es decir: ¡ya!. La otra es para que se muestre en el momento que indiquemos, ya sean unos segundos después o más tiempo… no sé exactamente cuanto tiempo, pero incluso días y meses después. La tercera (sí, ya se que te dije que había dos, pero…) es una especie de variación de la segunda, ya que también se puede indicar la periodicidad de dicha notificación (si se repite, etc.)

Es decir, que hay muchas posibilidades de usar las notificaciones del sistema (o toast notifications), así que, si además de lo que te explique aquí quieres saber más: Introducción a las notificaciones del sistema (Toast notification overview)

 

Lo primero que debes saber es que esto es para usarlo en las aplicaciones de Windows Store y que en el manifiesto de la aplicación tienes que indicar que quieres usar este tipo de notificaciones.

Abre el fichero Package.appxmanifest y en la primera ficha (Application UI) en la lista de las imágenes busca Badge Logo y selecciónala, en la parte de la derecha tendrás las opciones de notificaciones (notifications) en la lista Toast capable selecciona Yes tal como puedes ver en la figura 2.
De no hacerlo, las notificaciones simplemente ¡¡¡ NO APARECERÁN !!!

 

toast03
Figura 2

 

Una vez que tenemos esto, vamos a ver el código (en principio de Visual Basic, ya también el de C# o lo pongo más tarde o te pongo un enlace a Pastebin para cuando esté listo), de todas formas, los que usáis C# no os podéis quejar mucho, ya que la mayoría de los ejemplos de la documentación y otros sitios web están en C#, algo que no es tan habitual para los que prefieren usar Visual Basic, en fin…

 

Los pasos a seguir:

Crea un proyecto para la tienda de Windows (yo he creado el m´s básico).

Abre el fichero del manifiesto de la aplicación (Package.appxmanifest) y selecciona Yes en Toast capable (ver figura 2).

En MainPage.xaml vamos a crear una barra de aplicación (AppBar) con tres botones.
El diseño de esos botones los tomaremos del fichero StandardStyles.xaml (en la carpeta Common), pero como quiero cambiarles el texto para que me lo muestre en castellano, los he copiado y pegado en los recursos de la página (cambiándoles el nombre para que no haya conflictos, aunque en esta caso no los habría ya que los botones del fichero StandarStyles suelen estar comentados, al menos en la plantilla de las aplicaciones básicas.

Esos tres botones usarán distintos tipos de notificaciones, con idea de que sepas manejarte con varias de las posibilidades que tiene esto de los "toast notifications".

El primer botón envía una notificación inmediata usando un periodo largo, es decir, la notificación tardará más de lo habitual en quitarse, también está desactivado el audio (es una notificación silenciosa y de larga duración, jeje).

Al pulsar en el segundo botón mostrará una notificación a los 3 segundos y esta si que será con sonido y de duración normal.

El tercer botón se notificará de forma inmediata y otra más a los 10 segundos, ambas serán de larga duración y con sonido.

 

Aquí tienes una captura en pleno funcionamiento:

 

toast05
Figura 3. La aplicación en funcionamiento

 

Este es el código XAML completo, con la definición de los estilos de los tres botones.

 

<Page
    x:Class="Toast_notifications.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Toast_notifications"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <Style x:Key="PlayEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Inmediato"/>
            <Setter Property="Content" Value="&#xE102;"/>
        </Style>

        <Style x:Key="HelpEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Ayuda"/>
            <Setter Property="Content" Value="&#xE11B;"/>
        </Style>
        <Style x:Key="ClockEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="ClockAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Programado"/>
            <Setter Property="Content" Value="&#xE121;"/>
        </Style>
    </Page.Resources>
    
    <Page.BottomAppBar>
        <AppBar x:Name="bottomAppBar1" Padding="10,0,10,0">
            <Grid>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                    <Button Style="{StaticResource PlayEsAppBarButtonStyle}" 
                            Click="ButtonPlay_Click" />
                    <Button Style="{StaticResource ClockEsAppBarButtonStyle}" 
                            Click="ButtonClock_Click" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                    <Button Style="{StaticResource HelpEsAppBarButtonStyle}" 
                            Click="ButtonHelp_Click" />
                </StackPanel>
                
            </Grid>
        </AppBar>
    </Page.BottomAppBar>
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="80" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <!-- El título de la página -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="pageTitle" Grid.Column="1" Text="Prueba de toast notifications" 
                       IsHitTestVisible="false" 
                       Style="{StaticResource PageHeaderTextStyle}" />
            <Image x:Name="imgLogo" Grid.Column="2" Margin="10" 
                   Source="///Assets/SmallLogo.png" Stretch="Uniform" />
        </Grid>

    </Grid>
</Page>

 

Y este es el código de los tres botones Visual Basic:

Primero te pongo las dos importaciones que hay que añadir:

 

Imports Windows.UI.Notifications
Imports Windows.Data.Xml.Dom

 

Y este es el código de los tres botones, las explicaciones están en los comentarios.

 

Private Sub ButtonPlay_Click(sender As Object, e As RoutedEventArgs)

    ' La plantilla a usar, esta Text03 es:
    ' un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText03
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(toastXml.CreateTextNode("Cargando ..."))

    ' Si queremos que la duración sea larga
    ' Puede ser corta o larga, corta es la predeterminada
    Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    TryCast(toastNode, XmlElement).SetAttribute("duration", "long")

    ' Si queremos quitar el sonido
    ' (o indicar alguno en particular)
    ' tenemos que usar el elemento "audio"
    'Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    Dim audio As XmlElement = toastXml.CreateElement("audio")
    audio.SetAttribute("silent", "true")
    toastNode.AppendChild(audio)


    Dim toast As New ToastNotification(toastXml)
    ToastNotificationManager.CreateToastNotifier().Show(toast)
End Sub

Private Sub ButtonClock_Click(sender As Object, e As RoutedEventArgs)

    ' La plantilla a usar, esta Text03 es:
    ' un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText03
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(
        toastXml.CreateTextNode("A los 3 segundos después de haber pulsado en el botón."))
    toastTextElements(1).AppendChild(
        toastXml.CreateTextNode("Segundo texto."))

    ' Esto es para indicar que esta notificación se hará en el momento indicado
    Dim dueTime As DateTime = DateTime.Now.AddSeconds(3)
    Dim scheduledToast As New ScheduledToastNotification(toastXml, dueTime)

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast)

End Sub

Private Sub ButtonHelp_Click(sender As Object, e As RoutedEventArgs)
    ' La plantilla a usar, esta Text02 es:
    ' un texto de cabecera y un texto normal que puede ocupar dos líneas
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText02
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(
        toastXml.CreateTextNode("Esto se mostrará durante más tiempo ..."))
    toastTextElements(1).AppendChild(
        toastXml.CreateTextNode("Siempre puedes cerrar las notificaciones en la X superior."))

    ' Si queremos que la duración sea larga
    ' Puede ser corta o larga, corta es la predeterminada
    Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    TryCast(toastNode, XmlElement).SetAttribute("duration", "long")

    ' Esto es para indicar que esta notificación se hará en el momento indicado
    Dim dueTime As DateTime = DateTime.Now.AddSeconds(10)
    Dim scheduledToast As New ScheduledToastNotification(toastXml, dueTime)

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast)

    Dim toast As New ToastNotification(toastXml)
    ToastNotificationManager.CreateToastNotifier().Show(toast)

 

Ese es el código para C# (no he tardado tanto, ¿verdad? son las 06.35 y lo publiqué a eso de las 6.05)

 

Añade estas dos importaciones:

 

using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;

 

private void ButtonPlay_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text03 es:
    // un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText03;

    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primer elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(toastXml.CreateTextNode("Cargando ..."));

    // Si queremos que la duración sea larga
    // Puede ser corta o larga, corta es la predeterminada
    IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    ((XmlElement)toastNode).SetAttribute("duration", "long");

    // Si queremos quitar el sonido
    // (o indicar alguno en particular)
    // tenemos que usar el elemento "audio"
    // IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    XmlElement audio = toastXml.CreateElement("audio");
    audio.SetAttribute("silent", "true");
    toastNode.AppendChild(audio);

    ToastNotification toast = new ToastNotification(toastXml);
    ToastNotificationManager.CreateToastNotifier().Show(toast);
}

private void ButtonClock_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text03 es:
    // un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText03;

    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primer elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(
        toastXml.CreateTextNode("A los 3 segundos después de haber pulsado en el botón."));
    toastTextElements[1].AppendChild(
        toastXml.CreateTextNode("Segundo texto."));

    // Esto es para indicar que esta notificación se hará en el momento indicado
    DateTime dueTime = DateTime.Now.AddSeconds(3);
    ScheduledToastNotification scheduledToast = new ScheduledToastNotification(toastXml, dueTime);

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast);
}

private void ButtonHelp_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text02 es:
    // un texto de cabecera y un texto normal que puede ocupar dos líneas
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText02;
    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primero elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(
        toastXml.CreateTextNode("Esto se mostrará durante más tiempo ..."));
    toastTextElements[1].AppendChild(
        toastXml.CreateTextNode("Siempre puedes cerrar las notificaciones en la X superior."));

    // Si queremos que la duración sea larga
    // Puede ser corta o larga, corta es la predeterminada
    IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    (toastNode as XmlElement).SetAttribute("duration", "long");

    // Esto es para indicar que esta notificación se hará en el momento indicado
    DateTime dueTime = DateTime.Now.AddSeconds(10);
    ScheduledToastNotification scheduledToast = new ScheduledToastNotification(toastXml, dueTime);

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast);

    ToastNotification toast = new ToastNotification(toastXml);
    ToastNotificationManager.CreateToastNotifier().Show(toast);
}

 

 

Como comentario adicional, decirte que podemos "detener" una notificación si tenemos a nuestra disposición el objeto con la que se creó, ya que para detenerla tenemos que usar el método Hide de la función compartida CreateToastNotifier. A ese método Hide le tenemos que pasar una referencia al objeto que queremos detener. Yo esto lo he usado en la aplicación que he mandado a la tienda de Windows, en la que muestro la notificación mientras se carga una página web en el control WebView y la oculto cuando dicha página se ha terminado de cargar o lo que es lo mismo, intercepto el evento LoadComplete del control WebView, y ahí es donde quito la notificación.

Como es natural, el objeto "toast" usado para esa notificación no puede estar definido dentro de un sub, ya que así no sería accesible desde otra parte del código. Por tanto, en ese caso, el objeto toast usado para poder ocultarlo cuando queramos, lo tendríamos que definir fuera de cualquier método.

 

Espero que todo esto te sea de utilidad y para los que prefieren el C#, dadme unos minutos a que cree el proyecto en ese lenguaje y convierta el código, lo tacho porque ya está publicado.

 

Nos vemos.

Guillermo

Esta entrada fue publicada en cosas técnicas, mis cosas y etiquetada , , , , , , , , . Guarda el enlace permanente.

2 respuestas a Ejemplo sencillo de notificaciones (toast) para Windows Store

  1. nacho dijo:

    hola guille esto se puede adaptar para un rss de un blogs y que valla notificando las noticias podrias decirmo como podria modificar y lo mas importante que lo entienda para aprender que es la cuestion….gracias.

    saludos..

    • elGuille dijo:

      Sí se podría, pero no lo he probado y no tengo intención de hacerlo… 🙂 así que… el ejemplo ese que pides… no voy a poder proporcionártelo yo… pero seguro que habrá alguno entre los ejemplos que publican en la sección de developers para Windows 8[.1], eso sí, casi seguro que será en C#, porque ejemplos de VB escasean y mucho…
      ¡Suerte!

Los comentarios están cerrados.