Como gravar uma tag NFC?

Vamos iniciar uma nova solução Windows Phone no Visual Studio e nela vamos adicionar uma nova referência, a NdefLibrary. Para adicionar essa referência a sua solução do Visual Studio podemos usar o a ferramenta NuGet (Gerenciador de Pacotes), para isso devemos abrir o gerenciador e fazer uma busca por NDEF no campo de busca online e clicar em instalar.



Depois de adicionado vamos começar nosso desenvolvimento. No code behind da página inicial vamos adicionar a API da Proximity e depois criar três variáveis para uso dentro do código, uma variável instanciando a ProximityDevice que iremos usar para inicializar o NFC e utilizar o padrão do sistema e duas variáveis do tipo long para armazenar o ID do Subscribe e o Id da mensagem.

using Windows.Networking.Proximity;
using NdefLibrary.Ndef;
using System.Text;
using System.Runtime.InteropServices.WindowsRuntime;


private ProximityDevice device;
private long subscribeMessageId = -1;
private long publishingMessageId;


Inicializamos a váriavel de subscribeMessageId com o valor de -1 para usar como validação no método NFCBegin (que pode ser visto abaixo) enquanto estivermos fazendo leitura de uma tag o serviço não pode ficar disponível para leitura de outras tags, assim evitando um tap duplo ou uma leitura de valores diferentes. Após a validação do valor de subscribeMessageId no método a variável recebe um novo valor e retorna a variável para -1 no final do método MessageClientReceivedHandler.

public void NFCBegin()
{
     if (subscribeMessageId == -1)
     {
           subscribeMessageId = _device.SubscribeForMessage("NDEF", 
	   MessageReceivedHandler);
     }
}


O handler será responsável por descobrir o tipo da mensagem enviada e conforme o tipo fazer um tratamento, a variável specializedType receberá o tipo do NdefRecord enviado e essa variável será usada como parâmetro de validação de tratamento. Os tipos validados foram:
  • NdefMailtoRecord – Conteúdo para envio de E-mail
  • NdefUriRecord – URL para ser aberta no Browser
  • NdefSpRecord – Conteúdo de Smart Poster
  • NdefLaunchAppRecord – Inicialização de um aplicativo automaticamente
  • NdefTextRecord – Conteúdo em forma de texto

private void MessageReceivedHandler(ProximityDevice sender, ProximityMessage message)
        {
            var rawMsg = message.Data.ToArray();
            var ndefMessage = NdefMessage.FromByteArray(rawMsg);
            var tagContents = new StringBuilder();

            foreach (NdefRecord record in ndefMessage)
            {
                if (record.Id != null && record.Id.Length > 0)
                {
                    // Mostra o conteudo do Record Id
		      // Faça seu tratamento com o valor

                }
                if (record.Type != null && record.Type.Length > 0)
                {
                    // Mostra o conteudo do Record Type
		      // Faça seu tratamento com o valor
                }

                // Verifica o tipo do record enviado
                var specializedType = record.CheckSpecializedType(true);

                if (specializedType == typeof(NdefMailtoRecord))
                {
                    
                    var mailtoRecord = new NdefMailtoRecord(record);
                // Faça seu tratamento para as informações de email recebidas
                }
                else if (specializedType == typeof(NdefUriRecord))
                {

                    var uriRecord = new NdefUriRecord(record);
                    // Faça seu tratamento para as informações de Uri recebidas                }
                else if (specializedType == typeof(NdefSpRecord))
                {
                    
                    var spRecord = new NdefSpRecord(record);
                    // Faça seu tratamento para as informações de Smart Poster recebidas                
                }
                else if (specializedType == typeof (NdefLaunchAppRecord))
                {
                    
                    var launchAppRecord = new NdefLaunchAppRecord(record);
                    // Faça seu tratamento para as informações de App recebidas                
 		   } else if (specializedType == typeof (NdefTextRecord))
                {
                    
                    var launchAppRecord = new NdefTextRecord(record);
                    // Faça seu tratamento para as informações de Texto recebidas                
 		   }

                else
                {
                    // Outro tipo não validado nesse exemplo
                }

            subscribeMessageId 	= -1;
            }
}


Agora vamos adicionar a chamada do método NFCBegin no construtor e inicializar a variável de device com o valor padrão do sistema.

device = ProximityDevice.GetDefault();
NFCBegin();


Com isso já temos a parte de leitura de tag pronta na nossa aplicação e iremos iniciar a parte de escrita na tag. Iremos criar quatro métodos de escrita e um método para gravar na tag:

private void BtnLaunchApp (object sender, System.Windows.RoutedEventArgs e)
        {
            var record = new NdefLaunchAppRecord {Arguments = "Hello World"};
            record.AddPlatformAppId("WindowsPhone", "ID da App no WMAppManifest.xml");
            PublishRecord(record, true);
        }

private void BtnMailTo (object sender, System.Windows.RoutedEventArgs e)
        {
            var record = new NdefMailtoRecord
                             {
                                 Address = "email para qual quer enviar",
                                 Subject = "assunto do email",
                                 Body = "texto do email..."
                             };
            PublishRecord(record, true);
        }

private void BtnUri (object sender, System.Windows.RoutedEventArgs e)
        {
            var record = new NdefUriRecord { Uri = "http://www.seusite.com/" };
            PublishRecord(record, false);
        }

private void BtnText (object sender, System.Windows.RoutedEventArgs e)
        {
            var record = new NdefTextRecord
            {
                Text = content,
                LanguageCode = CultureInfo.CurrentCulture.TwoLetterISOLanguageName
            };

            PublishRecord(record, true);
        }

private void PublishRecord(NdefRecord record, bool writeToTag)
        {
            if (_device == null) return;
            StopPublishingMessage(false);

            var message = new NdefMessage { record };

            var msgArray = message.ToByteArray();
            publishingMessageId = _device.PublishBinaryMessage((writeToTag ? "NDEF:WriteTag" : "NDEF"), msgArray.AsBuffer(), MessageWrittenHandler);
        }

private void MessageWrittenHandler(ProximityDevice sender, long messageid)
        {
            StopPublishingMessage(false);
        }


Com esses quatro métodos estaremos cobrindo as possibilidades de escrita na tag usando a NDEF. O método PublishRecord faz o papel de realmente gravar as informações na tag, recebe por parâmetro a mensagem a ser gravada e um booleano validando se deve gravar. O método BtnLaunchApp grava na aplicação uma chamada para abrir um aplicativo especifico passando um argumento que será tratado na inicialização do aplicativo no método OnNavigatedTo.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            // Check if app was launched via LaunchApp tag
            if (NavigationContext.QueryString.ContainsKey("ms_nfp_launchargs"))
            {
                // Tratar na app o que fazer com o argumento
            }
        }


No método BtnMailTo será gerado um e-mail para o destinatário com o assunto e texto gravados na tag. No método BtnUri será gravado uma URL para abrir no aplicativo padrão do sistema, normalmente um Browser. No método BtnText será gravada uma string que deverá tratar no recebimento no próprio aplicativo. O método MessageWrittenHandler verifica se existe alguma mensagem sendo publicada no momento e pára de publicar caso seja verdade.

Podemos perceber que com poucas linhas de código podemos criar uma aplicação para escrita e leitura de tags no Windows Phone.

Last edited Aug 7, 2014 at 12:09 AM by brmontei, version 6