Actualizar cada minuto el icono (tile) de una aplicación de Windows Store hasta la hora indicada

Pues eso, un titulo más largo que el del artículo que publiqué hace unos días:
Actualizar el icono (tile) de una aplicación de Windows Store,
en el que te contaré cómo indicarle a Windows que actualice lo que se muestra en el icono de la aplicación (tile), pero incluso cuando dicha aplicación ya está cerrada, además esa actualización se hará cada "x" tiempo y hasta cuando tu digas (la cantidad de minutos u horas que quieras que duren esas actualizaciones).

El código te lo mostraré primero para Visual Basic y cuando lo tenga listo en C# lo agregaré a esta misma "página" (con fecha del domingo 23 de diciembre de 2012 ya está el código de C#, pero lo he puesto al final del todo y sin usar el fondo negro).

Dicho esto, crea una nueva aplicación para Windows Store (la más básica es suficiente).

En el código del evento OnNavigatedTo de MainPage añade esta llamada al método que hará todo el trabajo: asignarTiles.

 

Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    asignarTiles()
End Sub

 

Y ahora viene cómo hacer esto de modificar (si quieres, llámalo notificar) el contenido del icono de la aplicación (conocido como tile por los que ponen nombres a estas cosas nuevas que van saliendo). Pero para hacer esa modificación no tendremos que usar ningún temporizador (timer) simplemente usaremos una serie de asignaciones a un objeto del tipo TileUpdater creado a través del método CreateTileUpdaterForApplication de la clase TileUpdateManager a través del método AddToSchedule de forma que le digamos lo que se mostrará en el icono (ya sea el grande -ahora hablamos de ese icono- o el pequeño) y, lo más importante, cuándo se mostrará.

Nota:

Este código está adaptado del ejemplo Clock Tile de Dave Smits.

Te dejo el código y espero que lo comprendas… si tienes dudas pregunta en los comentarios de este mismo post… eso si antes no te lo he explicado con más detalle.

Recuerda que el cuadro del código puede tener scroll y no lo veas al completo…

 

Lo que sí (o también, si ya te he explicado lo que te iba a explicar) te voy a decir que al crear un nuevo proyecto para Windows Store (al menos del más elemental) el icono ancho no estará y por tanto el icono (o tile) de la aplicación se mostrará en el formato cuadrado (pequeño). Esa imagen es la que se llama Logo.png en la carpeta Assets y su tamaño es de 150×150. Para tener el logo de tamaño ancho, necesitarás una imagen de 310×150 a la que tendrás que darle el nombre WideLogo.png. Si no haces esto, este ejemplo no compilará.

 

''' <summary>
''' Crear la lista de notificaciones al icono (tile)
''' Se crearán los necesarios para las próximas 4 horas
''' notificando cada minuto
''' </summary>
''' <remarks>
''' Basado en el código de Clock Tile de Dave Smits
''' </remarks>
Private Sub asignarTiles()
    Dim tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication()

    Dim now As DateTime = DateTime.Now
    ' aquí está el truco... crear tiles para un buen rato...
    Dim planTill As DateTime = now.AddMinutes(30) ' .AddHours(4) ' .AddMinutes(15)

    Dim updateTime = New DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0).AddMinutes(1)

    Dim plannedUpdated = tileUpdater.GetScheduledTileNotifications()
    If plannedUpdated.Count > 0 Then
        ' Asignar a updatetime la última fecha de la colección (o la que sea mayor)
        updateTime = plannedUpdated.Select(Function(x) x.DeliveryTime.DateTime).Union({updateTime}).Max()
    End If
    Const sXml = "<tile><visual>" &
                        "<binding template=""TileSquareText02""><text id=""1"">{0}</text><text id=""2"">{2}</text></binding>" &
                        "<binding template=""TileWideText01""><text id=""1"">{0}</text><text id=""2"">{1}</text>" &
                            "<text id=""3""></text><text id=""4""></text><text id=""5""></text></binding>" &
                "</visual></tile>"

    Dim tileXmlNow = String.Format(sXml, now.ToString("HH:mm"),
                                         now.ToString("dddd, dd MMMM yyyy"),
                                         now.ToString("dd/MMM/yyyy"))
    Dim documentNow As New XmlDocument()
    documentNow.LoadXml(tileXmlNow)

    tileUpdater.Update(New TileNotification(documentNow) With {.ExpirationTime = now.AddMinutes(1)})

    Dim startPlanning = updateTime
    While startPlanning < planTill

        Try
            Dim tileXml = String.Format(sXml, startPlanning.ToString("HH:mm"),
                                              startPlanning.ToString("dddd, dd MMMM yyyy"),
                                              startPlanning.ToString("dd/MMM/yyyy"))
            Dim document As New XmlDocument()
            document.LoadXml(tileXml)

            Dim deliveryTime = New DateTimeOffset(startPlanning)
            Dim scheduledNotification = New ScheduledTileNotification(document, deliveryTime)
            scheduledNotification.ExpirationTime = startPlanning.AddMinutes(1)

            tileUpdater.AddToSchedule(scheduledNotification)

        Catch e As Exception
            Debug.WriteLine("exception: " & e.Message)

        End Try

        startPlanning = startPlanning.AddMinutes(1)
    End While

End Sub

 

Bueno, y esto es todo… si cierras la aplicación (sólo te mostrará una pantalla negra) verás que el icono se sigue actualizando y cuando pase el tiempo indicado (en este ejemplo es de 30 minutos) se asignará el texto original.

El tiempo total en el que se estarán mostrando las notificaciones es el indicado en la definición de la variable PlanTill:

Dim planTill As DateTime = now.AddMinutes(30)

 

Por cierto, creo que el número máximo de "actualizaciones / notificaciones" al tile de la aplicación es de 4096, así que… lo mismo habría que tener en cuenta que no se sobrepase esa cantidad… (tendré que probar si da error o no al pasar de esa cantidad).

 

Espero que te sea de utilidad.

Nos vemos.

Guillermo

P.S.

El "estilo" del código es el que Visual Studio 2012 utiliza cuando está en modo "Dark"… a mi no me acaba de convencer…

 

Nota del 23/Dic/12: el código de C#

/// <summary>
/// Crear la lista de notificaciones al icono (tile)
/// Se crearán los necesarios para las próximas 4 horas
/// notificando cada minuto
/// </summary>
/// <remarks>
/// Basado en el código de Clock Tile de Dave Smits
/// </remarks>
private void asignarTiles()
{
    var tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();

    DateTime now = DateTime.Now;
    // aquí está el truco... crear tiles para un buen rato...
    DateTime planTill = now.AddMinutes(30); // .AddHours(4)

    var updateTime = new DateTime(now.Year, now.Month, now.Day, 
                                  now.Hour, now.Minute, 0).AddMinutes(1);

    var plannedUpdated = tileUpdater.GetScheduledTileNotifications();
    if (plannedUpdated.Count > 0)
    {
        // Asignar a updatetime la última fecha de la colección (o la que sea mayor)
        updateTime = plannedUpdated.Select(
            x => x.DeliveryTime.DateTime).Union(new[] { updateTime }).Max();
    }

    const string sXml = 
        @"<tile><visual>
            <binding template=""TileSquareText02"">
                <text id=""1"">{0}</text><text id=""2"">{2}</text>
            </binding>
            <binding template=""TileWideText01"">
                <text id=""1"">{0}</text><text id=""2"">{1}</text>
                <text id=""3""></text><text id=""4""></text><text id=""5""></text>
            </binding>
        </visual></tile>";

    var tileXmlNow = String.Format(sXml, now.ToString("HH:mm"),
                                         now.ToString("dddd, dd MMMM yyyy"),
                                         now.ToString("dd/MMM/yyyy"));
    XmlDocument documentNow = new XmlDocument();
    documentNow.LoadXml(tileXmlNow);

    tileUpdater.Update(new TileNotification(documentNow) { ExpirationTime = now.AddMinutes(1) });

    // Este bucle while se puede cambiar por este for:
    // for (var startPlanning = updateTime; startPlanning < planTill; startPlanning = startPlanning.AddMinutes(1))
    var startPlanning = updateTime;
    while (startPlanning < planTill)
    {
        try
        {
            var tileXml = String.Format(sXml, startPlanning.ToString("HH:mm"),
                                              startPlanning.ToString("dddd, dd MMMM yyyy"),
                                              startPlanning.ToString("dd/MMM/yyyy"));
            XmlDocument document = new XmlDocument();
            document.LoadXml(tileXml);

            var deliveryTime = new DateTimeOffset(startPlanning);
            var scheduledNotification = new ScheduledTileNotification(document, deliveryTime);
            scheduledNotification.ExpirationTime = startPlanning.AddMinutes(1);

            tileUpdater.AddToSchedule(scheduledNotification);
        }
        catch (Exception e)
        {
            Debug.WriteLine("exception: " + e.Message);
        }
        startPlanning = startPlanning.AddMinutes(1);
    }
}

 

3 comentarios en “Actualizar cada minuto el icono (tile) de una aplicación de Windows Store hasta la hora indicada

  1. link shortner

    Helpful info. Lucky me I found your website accidentally, and I’m stunned why this coincidence didn’t took place in advance!
    I bookmarked it.

    Responder

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *