Tile – Windows Phone – Coding (Portuguese)

 

Então caras, por aí é bem difícil achar informações concentradas sobre como implementar um tile para uma App/um Aplicativo para Windows Phone(WP).

Antes disso indico você ler um post no blog do Quezado sobre a Anatomia de um Tile. No post do Quezado você encontrará definições sobre tiles, formas de interação, como os tiles são inseridos na tela inicial de um WP, dimensão (173×173), dicas de design, boas práticas e etc.

Alguns dos tiles do Windows Phone

Aqui no meu post mostro como implementar um Tile dinâmico, ou seja, adicionado pela própria aplicação, isso pode ser feito procurando por um tile que já foi adicionado a tela ou criando um tile (caso de o tile não estar presente na tela inicial do WP.

Então vamos lá:

  • Para criar um tile dinâmico você precisa primeiro criar uma tarefa que será responsável por atualizar seu tile enquanto sua app estiver sendo utilizada pelo usuário e quando ela não estiver sendo utilizada. Essa parte de implementação do código chamamos de Scheduled Task.  Na MSDN Library, seção Background Agents Overview tem definição para uma Scheduled Task:

Uma Scheduled task  permite a uma aplicação executar código em background mesmo que a aplicação não esteja rodando em segundo plano.  Os diferentes tipos de Scheduled Tasks são projetados para diferentes tipos de cenários.

  • Crie um novo projeto dentro da sua atual solução, o novo projeto é do tipo: Windows Phone Scheduled Agent. Repare que no campo Name é uma boa prática colocar a que projeto a Scheduled Task se refere.

    Novo Projeto para adicionar na atual solução

  • Após criar o projeto terás a seguinte estrutura:

Estrutura dos Arquivos do Projeto do TaskAgent

O arquivo que você irá utilizar é o ScheduledAgent.cs. Esse arquivo contém o código para desenhar o Tile. Um código já será gerado, substitua o método OnInvoke da sua Classe por este código:

 //Método que é chamado quando a task é invocada. Aqui que se procura o tile, desenha-se a imagem e se atualiza o Tile.
        protected override void OnInvoke(ScheduledTask task)
        {
            if (task is PeriodicTask)
            {
                //Criar a imagem
                createImage(1, "Titulo", "Subtitulo");
                //Procurar o tile
                ShellTile TileToFind = ShellTile.ActiveTiles.First();
 
                if (TileToFind != null)
                {
                    //Você deve preencher os dados para atualizar o Tile. Para isso você instancia um novo StandardTileData
                    //Reparte no caminho da propriedade BackBackgroundImage. O isostore indica que a imagem está salva no Windows Phone.
                    StandardTileData NewTileData = new StandardTileData
                    {
                        BackgroundImage = new Uri("Background.png", UriKind.Relative),
                        Count = 0,
                        BackBackgroundImage = new Uri("isostore:/Shared/ShellContent/testTile.jpg", UriKind.Absolute)
                    };
                    //Com os dados alterados você poderá atualizar o Tile.
                    TileToFind.Update(NewTileData);
                }
                else
                {
                    //O Tile não está "pinnado".
                }
 
            }
 
            NotifyComplete();
        }
  • Desenhar o tile: Na linha 6 do código que está dentro do método OnInvoke há uma chamada para o método createImage(int idx, string title, string subtitle). O método createImage tem como função desenhar a imagem que será utilizada no tile, ou seja, posicionar os textos, colocar a imagem de fundo, salvar a imagem para ser usada na atualização do Tile. O método createImage faz parte da sua classe ScheduledAgent. Esse é o código:

 

 public void createImage(int idx, string title, string subtitle)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                //Para desenhar a imagem vamos manipular uma imagem já existente no seu projeto
                //Essa imagem é a que ficará como background do texto.
                var logo = new BitmapImage(new Uri("tileEsc.png", UriKind.Relative));
                logo.CreateOptions = BitmapCreateOptions.None;
 
                //Verificar se o arquivo da imagem já está aberto e prontinho esperando a nossa manipulação.
                logo.ImageOpened += (sender, e) =>
                {
                    //Passamos os parâmetros de dimensão referentes as dimensões do Tile.
                    //Pedi para você ler no início sobre dimensões e etc e tal no blog do Quezado.
                    var bmp = new WriteableBitmap(173, 173);
 
                    //Setamos a propriedade Source da Imagem
                    var img = new Image { Source = logo };
 
                    //Daqui para baixo vamos construir os blocos de texto e seus posicionamentos.
                    var bl = new TextBlock();
 
                    bl.Foreground = new SolidColorBrush(Colors.White); //Cor do Texto
                    bl.FontSize = 20.0; //Tamanho da Fonte
                    bl.Text = title; //O texto
 
                    var bl2 = new TextBlock();
                    bl2.Foreground = new SolidColorBrush(Colors.White);
                    bl2.FontSize = 60.0;
                    bl2.Text = "#" + idx.ToString();
 
                    var bl3 = new TextBlock();
                    bl3.Foreground = new SolidColorBrush(Colors.White);
                    bl3.FontSize = 20.0;
                    bl3.Text = subtitle;
 
                    var transf = new TranslateTransform(); //Utilizado para auxiliar no posicionamento
                    transf.X = 12;
                    transf.Y = 120;
 
                    var transf2 = new TranslateTransform();
                    transf2.X = 12;
                    transf2.Y = 62;
 
                    var transf3 = new TranslateTransform();
                    transf3.X = 12;
                    transf3.Y = 142;
 
                    var tt = new TranslateTransform();
                    tt.X = 173 - logo.PixelWidth;
                    tt.Y = 173 - logo.PixelHeight;
 
                    //Com os objetos já manipulados então se chega ao momento de renderizar para montar nossa imagem final.
                    //"Taca" bmp.Render nesses caras...
                    bmp.Render(img, tt);
 
                    bmp.Render(bl, transf);
                    bmp.Render(bl2, transf2);
                    bmp.Render(bl3, transf3);
 
                    //O invalidate não é pra invalidar :P É utilizado para redesenhar nossa imagem inicial.
                    bmp.Invalidate();
 
                    //Desenhamos! Agora o momento é de salvar no Isolated Storage!
                    //Para poder ser acessado mesmo que a app esteja fechada.
                    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        var filename = "/Shared/ShellContent/testTile.jpg";
                        using (var st = new IsolatedStorageFileStream(filename, FileMode.Create, FileAccess.Write, store))
                        {
                            bmp.SaveJpeg(st, 173, 173, 0, 100);
                        }
                    }
                };
 
            });
        }

Com os trechos de código que passei acima você deixa agora a classe ScheduledTask de lado e pode partir para onde iremos chamar a Task. Para isso eu adicionei um botão na minha view (lá no XAML) e esse botão inicia todo o processo. Adicionei o seguinte código:

private void btnAddTile_Click(object sender, RoutedEventArgs e)
        {
            //iniciar background agent
            PeriodicTask periodicTask = new PeriodicTask("PeriodicAgent");
 
            periodicTask.Description = "Live Tile Update - TileProject";
            periodicTask.ExpirationTime = System.DateTime.Now.AddDays(1);
 
            // Se o agente já está registrado no sistema, você deve remover.
            if (ScheduledActionService.Find(periodicTask.Name) != null)
            {
                ScheduledActionService.Remove("PeriodicAgent");
            }
 
            ScheduledActionService.Add(periodicTask);
            // Esse método LaunchForTest é utilizado para disparar a Task, para facilitar a utilização e você não ter que esperar em torno de 30 minutos para a execução da task. Quando você for fazer o pacote final da App remova esse trecho.
            ScheduledActionService.LaunchForTest(periodicTask.Name, TimeSpan.FromSeconds(10));
        }

Para ter certeza de que sua task está rodando é só verificar no Settings – Applications – Background Tasks  do seu WP.

Com os trechos de código acima você já pode criar seu mecanismo para atualizar o Tile da sua App. Eu dei um exemplo com a interação do usuário através do clique em um botão na aplicação, mas o mesmo código pode ser usado em outro trecho da aplicação para deixar rodando a task esperando o usuário adicionar a Tile da forma padrão  e depois a task atualiza o Tile tornando este dinâmico.

Então galera, o código está disponível no meu Github, o Github do jungle dev :) Pode pegar, baixar, fazer download, colocar na sua máquina… E  contribuir!

“Falores”!

6 Comments

  • Pingback: Anatomia de um Tile | quezado

  • Pingback: Anatomy of a Tile | quezado

  • Rodrigo Borges Soares
    30 de dezembro de 2011 - 18:42 | Permalink

    Muito bom! Valeu! :)

  • Mauro
    30 de dezembro de 2011 - 22:26 | Permalink

    Boa iniciativa ;-)

  • Pingback: Anatomia de um Tile - Windows Phone Brasil : Windows Phone Brasil

  • Pingback: Como implementar um Tile para aplicativos do Windows Phone | Gonow Tecnologia - Consultoria e Outsourcing em Tecnologia

  • Deixe uma resposta

    O seu endereço de email não será publicado Campos obrigatórios são marcados *


    *

    Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

    Social Widgets powered by AB-WebLog.com.