Desenvolvimento - Mobile

Criando um aplicativo móvel com armazenamento em XML e sincronização de dados com a WEB - Parte 1

Neste artigo apresento as técnicas encapsuladas do .NET Compact Framework, desenvolvendo uma aplicativo móvel que armazena os dados em um XML e por fim espelha suas modificações em um servidor remoto.
TECNOLOGIAS USADAS: VB.NET 2005, Visual Studio 2005, Mobile Applications, Web Services e XML.

por Ciniro Nametala



Estarei nesse artigo demonstrando a todos como é fácil e abstraído os métodos que permeiam o desenvolvimento de aplicativos móveis quando trabalhando .NET. Usaremos a linguagem Visual Basic 2005 e Visual Studio 2005. Ainda, estaremos armazenando todas as nossas informações em arquivos do tipo XML, dispensando o banco de dados compacto da Microsoft, o SQL Server CE. Por fim e na próxima parte deste artigo, continuaremos, desenvolvendo uma solução moderna, que com o uso de Web Services enviará a um servidor remoto os dados trabalhados dentro de nosso aplicativo móvel, fazendo uma sincronização e proporcionando consultas aos dados diretamente de um endereço WEB qualquer. Espero que este artigo introduza muitas pessoas neste fantástico mundo da mobilidade tão valorizado nos dias de hoje e tão fácil de ser abraçado usando as ferramentas da plataforma .NET.

Então vamos por a mão na massa...

Mobilidade, Armazenamento, Emuladores, enfim Definições

Se pararmos e olharmos para trás vamos perceber que as implementações móveis são um sonho do homem informatizado que vem de muito tempo. Desde que se criaram o PC e suas ramificações, muitas tentativas partindo de vários fabricantes se tornaram sucesso e fracasso nas mãos dos amantes da tecnologia. Mas se parássemos pra nos perguntar: Onde estava a Microsoft antes dos sofisticados dispositivos móveis que hoje se disseminam por ai? E o que ela oferecia no mercado antes da robusta plataforma .NET e do suporte ao desenvolvimento das Mobile Applications?

Bem, antes, levando para a prática e indo diretamente ao ponto, tínhamos uma linguagem específica e com muitos problemas em sua terceira versão chamada eVB, ou Embed Visual Basic, uma pseudo-extensão do VB Clássico que possuía API´s customizadas rodando também em um ambiente customizado, esta baseada diretamente em scripts e com tipagem de dados muito fraca, suporte a tratamento de erros que se limitavam por exemplo ao "infantil" "On Error:". Com essa necessidade de uma base sólida para oferecer aos programadores que desejavam desenvolver aplicativos móveis então foi idealizada e constituída a .NET Compact Framework, uma versão não só mais enxuta, mas específica para este tipo de criação, herdando valores da versão completa do Framework .NET e ainda oferecendo controles, biblioteca de classes prontas, além de mais uma infinidade de facilidades.

Levando em conta as reduzidas capacidades dos dispositivos móveis podemos colocar que armazenamento de dados, tamanho de tela, memória são limitações que o .NET CF (.NET Compact Framework) dribla de forma elegante. Além do gerenciamento automático de memória e adaptação padrão em tamanho de tela, foi desenvolvido o Microsoft SQL Server CE, uma edição compacta destinada e desenhada para rodar em dispositivos que possuam limitações características e sistema Windows CE. Nele temos uma interface de fácil trabalho, criamos bancos, tabelas, executamos consultas, dentre outras funções pertinentes a um banco de dados.

E por fim você notará que é muito fácil e intuitivo desenvolver dentro do Visual Studio 2005. Não existindo diferenças de metodologia de quando se desenvolve Web ou Win Applications, usaremos livremente a linguagem que gostamos e trabalharemos da mesma forma RAD, arrastando controles para um molde de tela. Ao executar o debug, você entrará em contato com o emulador desejado, este cria uma instância perfeita de um dispositivo na memória do seu PC, de dentro desta instância roda seu aplicativo. Existem vários tipos de emuladores de vários tipos de dispositivos, para ter acesso a eles saiba que podemos encontrá-los nos sites das fabricantes, sugiro um bom site http://www.openwave.com/.

Bom o papo foi longo, mas vamos ao que interessa: Codificar.

Construindo os alicerces...

Nosso aplicativo terá como função listar e manipular a relação de bois cadastrados dentro de uma fazenda. O usuário poderá inserir, remover e salvar a lista de animais. Teremos uma interface principal que dará acesso aos outros formulários e na próxima parte desse artigo estarei ensinando como enviar estas informações a um servidor WEB utilizando Web Services.

Iniciando vamos executar a rotina clássica de criação de projeto clicando seguidamente em File>New Project> Na caixa Project Types escolhemos na árvore de projetos Visual Basic>Smart Device>Pocket PC 2003> e na caixa Templates clicamos sobre Device Application> Na caixa de texto abaixo damos um nome ao nosso projeto, no caso agroTeste. Sua janela New Project deve ficar como a exibida abaixo:

Criado o projeto repare que o Visual Studio exibe uma imagem mostrando o dispositivo móvel (Muito Legal!), se você não desejar que ela seja exibida clique sobre o formulário e defina a propriedade Skin como False. Vamos agora definir o esqueleto que vai rodar nossa aplicação, ou seja, vamos criar os formulários e neles adicionar os controles necessários. Nosso projeto será composto de três formulários, cada um deles com uma proposta diferenciada. Teremos um principal que dará acesso aos outros com o dito acima, outro para consultas e manipulação das informações e no terceiro um botão que executará a rotina que chama o Web Service e envia os dados para a WEB. Vamos começar construindo o Formulário Principal. Para isso aproveitaremos o formulário criado por padrão na construção do projeto. Vá até a sua Solution Explorer e renomeie o Form1.vb para frmPrincipal.vb clicando com o botão direito sobre ele e depois em Rename. Feito isso siga as instruções abaixo para modificar as propriedades do formulário e seus componentes:

Form (frmPrincipal.vb)
BackColor: Green
Text: Agro
Name: frmPrincipal
MainMenu: mainMenu1

Label
Font: Tahoma; 26pt; style=Bold
Text: AgroSystem
TextAlign: TopCenter

MainMenu
Name:mainMenu1
Clique sobre a indicação TypeHere, na barra de menu que aparece e vá definindo os menus e sub-menus de acordo com a seguinte árvore:

Feita a colocação dos controles o seu formulário deve ficar com a aparência apresentada abaixo:

Crie mais dois formulários, para isso clique com o botão direito em cima do nome do seu projeto na Solution Explorer, depois Add>New Item> Na janela apresentada selecione na caixa Add New Item - AgroTeste a opção Windows Form, na caixa de texto Name, dê o nome de frmConsultas.vb para o primeiro Formulário criado e frmWEB.vb para o segundo. Agora sua Solution Explorer deve estar com a seguinte configuração:

Defina os novos formulários inseridos de acordo com as características exibidas abaixo, lembrando-se de remover os MainMenu´s inseridos por padrão em cada adição de formulário feita ao projeto:

Form (frmConsultas.vb)
BackColor: Green
Text: AgroMaster - Consultas
Name: frmConsultas

Label
Font: Tahoma; 10pt; style=Bold
ForeColor: White
Text: Relação de Bovinos da fazenda
TextAlign: TopCenter
Name: lblTitulo

Label
Font: Tahoma; 10pt; style=Bold
ForeColor: White
Text: Nome:
Name: lblNome

Label
Font: Tahoma; 10pt; style=Bold
ForeColor: White
Text: Peso:
Name: lblPeso

Button
BackColor: White
Text: Remover
Name: cmdRemover

Button
BackColor: White
Text: Adicionar
Name: cmdAdicionar

Button
BackColor: White
Text: Salvar
Name: cmdSalvar

TextBox
Name: txtNome

TextBox
Name: txtPeso

Form (frmWEB.vb)
BackColor: Green
Text: WEB
Name: frmWEB

Label
ForeColor: White
Text: Clique aqui para enviar seus dados para a internet. Eles estarão acessíveis através do seu site.
TextAlign: TopCenter
Name: lblInfo

Button
BackColor: White
Text: Sincronizar com WEB
Name: cmdSincronizar

Confira abaixo como devem ficar a aparência dos formulários construídos:

Levantando as paredes...

Bem. Vamos agora a primeira parte de codificação do nosso projeto. No formulário frmPrincipal.vb, temos um MainMenu, dentro dele teremos os itens que ao serem clicados chamarão nossos outros formulários. Não temos aqui a necessidade de indicar que este é o formulário mestre, mas teremos que chamar todos os outros de forma que eles sejam apresentados como janelas de diálogo, assim, terão sempre que ser fechados antes do formulário principal. Para isso dê duplo click sobre os submenus do MainMenu e insira os códigos:

Public Class frmPrincipal

"FECHA A APLICAÇÃO

Private Sub mnuSair_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuSair.Click

Application.Exit()

End Sub

"CHAMA O FRMWEB

Private Sub mnuWeb_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

frmWEB.ShowDialog()

End Sub

"CHAMA O FRMCONSULTAS

Private Sub mnuConsultas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuConsultas.Click

frmConsultas.ShowDialog()

End Sub

End Class

Rode sua aplicação (F5) e teste.
Construído este formulário vamos partir para a construção do frmConsultas.vb. XML - Armazenando com uma linha de código

Como dito, vamos armazenar nossos dados em um arquivo texto formato *.xml, para isso devemos criar o arquivo, ou seja, quando o programa for inicializado pela primeira vez, o arquivo é criado. Nos próximos acessos, os dados serão trazidos diretamente dessa fonte de dados. Para isso definiremos uma variável privada no topo de nossa classe, esta do tipo DataTable, trabalharemos em cima dela. Depois criamos a estrutura da tabela que armazenará os dados. E por fim fazemos uma leitura para definir se o arquivo *.xml já existe ou não através dos métodos importados do namespace System.IO. Caso eles já existam, enviamos eles para dentro de nossa DataTable e esta por sua vez é vinculada ao componente GridView que exibe os dados ao usuário. Veja o código abaixo:

Imports System.Data "Namespace para trabalharmos com dados

Imports System.IO "Namespace que permite usar métodos com o arquivo

Public Class frmConsultas

Private dts As DataTable "Variável pública da classe

Private Sub CriaEstrutura() "Método que cria a tabela no datatable dts

dts = New DataTable("tb_bovino")

dts.Columns.Add("nome_bovino")

dts.Columns.Add("peso_bovino")

End Sub

Private Sub frmPrincipal_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

CriaEstrutura() "Chama o método

"Se o XML existe no caminho especificado então

If File.Exists("My Documents\BD_BOVINO.xml") Then

Try

dts.ReadXml("My Documents\BD_BOVINO.xml") "tenta a leitura, se der erro

Catch

"escreve no XML a estrutura construida no metodo CriaEstrutura()

dts.WriteXml("My Documents\BD_BOVINO.xml")

End Try

"vinculamos o dts ao GridView

dtgBovinos.DataSource = dts

Else

"Se o arquivo não existe, criamos

File.Create("My Documents\BD_BOVINO.xml")

"Pede que o usuário reentre na aplicação

MsgBox("O sistema criou o arquivo de dados que não existia, por favor, reinicie a sua aplicação para que ele torne-se ativo!")

Application.Exit()

End If

End Sub

End Class

Podemos perceber aqui o quanto é fácil verificar a existência ou criar um novo arquivo em um caminho dado através do namespace System.IO, sem falar do nível de abstração concebido quando chamamos métodos do tipo DataTable.WriteXml(""). É fácil assim mesmo, o .NET encapsula todas funções críticas deixando ao programador, uma única tarefa: Render o serviço. Vamos agora as partes interessantes do código.

Em primeiro lugar criamos a variável "dts" que é usada em toda classe. Na rotina CriaEstrutura(), inicializamos a variável pública e adicionamos duas colunas a tabela, "nome_bovino" e "peso_bovino", por default ambas do tipo String. A rotina é chamada no método Load() do formulário e em seguida através do método File.Exists(""), verificamos a existência do XML, se ele existe, carregamos seus dados para dentro do "dts", pelo método dts.ReadXml(""). Se der erro, a estrutura criada é convertida em dados e guardada dentro do arquivo, pelo método dts.WriteXml(""). Caso o arquivo não exista ele é criado através do File.Create("") e nossa aplicação se fecha.

Se você rodar seu aplicativo agora(F5), vai perceber uma janela avisando que o arquivo de dados foi criado e que você deve entrar novamente na aplicação. Fazendo isto, apresentada será a tela principal, no menu, acesse o formulário de consultas, veja que o GridView aparece vazio. Vamos agora criar os métodos para inserir, remover e salvar os dados.

Inserir e Salvar

Pare seu debug (não precisa fechar o emulador), volte ao frmConsultas.vb e click duas vezes sobre o botão adicionar e insira o seguinte código dentro do disparo do evento:

Private Sub cmdAdicionar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAdicionar.Click

If (txtNome.Text.Trim() <> "") Or (txtPeso.Text.Trim() <> "") Then

Dim linha As DataRow = dts.NewRow()

linha("nome_bovino") = txtNome.Text

linha("peso_bovino") = txtPeso.Text

dts.Rows.Add(linha)

dtgBovinos.Refresh()

txtNome.Text = ""

txtPeso.Text = ""

Else

MsgBox("Preencha todos os campos!")

End If

End Sub

Primeiro impedimos a inserção de valores nulos, se os valores forem válidos, criamos uma nova linha do "dts" e esta é passada para nossa variável "linha" do tipo DataRow. Em seguida os campos "nome_bovino" e "peso_bovino" são setados com os valores digitados pelo usuário, a variável, registro, é adicionada ao "dts", como ele está vinculado ao GridView, basta que atualizemos o componente através do método Refresh(). Por fim setamos as caixas de texto como vazio.

Se você rodar sua aplicação neste ponto(F5), notará que ao inserir os valores e mandar adiciona-los, os mesmos são exibidos na tela. Mas, detalhe, eles não estão salvos, se você fechar o aplicativo e voltar os dados serão perdidos. Para habilitar o método que salva as informações do "dts", dê um duplo click no botão Salvar, e insira o seguinte código:

Private Sub cmdSalvar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSalvar.Click

dts.WriteXml("My Documents\BD_BOVINO.xml")

MsgBox("Salvo com sucesso!")

End Sub

Aqui vemos mais uma vez o método DataTable.WriteXml("") em ação. Ele escreverá no arquivo criado as atualizações do nosso sistema.

Selecionando e Removendo

Agora faremos o seguinte. O usuário deve clicar sobre a linha em que está o animal, e os dados deste devem ser exibidos nas caixas de texto. Assim inserimos o código abaixo, vinculado ao evento CurrentCellChange() do GridView:

Private Sub dtgBovinos_CurrentCellChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dtgBovinos.CurrentCellChanged

Dim i As Integer = dtgBovinos.CurrentRowIndex()

If (i <> -1) Then

txtNome.Text = dts.Rows(i)("nome_bovino").ToString()

txtPeso.Text = dts.Rows(i)("peso_bovino").ToString()

End If

End Sub

Um índice é criado e recebe a posição da linha clicada, se for diferente de -1(Nada selecionado), ele busca os dados pela linha do "dts", pois este está vinculado ao GridView. Passando o indice, o campo e convertendo para String, as caixas de texto recebem os valores selecionados.

Selecionada uma linha, fica agora a cargo do botão Remover, a exclusão da mesma do "dts" e conseqüente eliminação da sua exibição no Grid.

O DataTable é um componente que pode ser alterado, mas suas alterações são realmente efetuadas quando damos o comando para isso, ou seja, quando você exclui uma linha, ou altera uma linha do DataTable, elas não são realmente alteradas ou excluídas, são marcadas com uma flag, isto possibilita que o programador cancele as operações efetuadas, ou mesmo as efetue de fato. Veja como fica no código a rotina Click() do botão Remover:

Private Sub cmdRemover_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRemover.Click

Dim i As Integer = dtgBovinos.CurrentRowIndex()

If (i <> -1) Then

dts.Rows(i).Delete()

dts.AcceptChanges()

dtgBovinos.Refresh()

End If

End Sub

Repare que após receber o indice da linha clicada e testar se é algo selecionado(diferente de -1), removemos ela através do método dts.Rows(i).Delete(), aqui, a mesma é marcada com uma flag de linha excluida, mas ainda temos a opção de cancelar a operação, a exclusão é de fato efetuada quando chamamos o método dts.AcceptChanges() que comita a deleção. Então atualizamos no componente GridView(), que não mais exibe a linha excluida.

Rode seu aplicativo e teste todas as funções.

Finalizando...

Contabilizando pessoal, foram até aqui míseras 58 linhas de código, isso mesmo, com apenas 58 linhas de código criamos uma interface completa para um dispositivo móvel com acesso a dados, verificação de arquivos, criação de xml, trabalhos com inclusão, remoção e apresentação em forma tabular. Espetacular!

Podemos criar aplicações robustas e confiáveis dentro do Visual Studio 2005, a .NET CF vem evoluindo, temos uma infinidade de classes a serem exploradas e usadas, o assunto do desenvolvimento de Mobile Applications é extenso, estudando, percebe-se que com a convergência ferramentas novas aparecem a cada dia focadas nesta área, e as implementações se tornam mais fáceis.

Na próxima parte deste artigo, trataremos de um outro assunto, também muito interessante, vinculação dos Web Services a aplicação criada aqui. Espero que todos tenham gostado deste e obrigado aos que lerão, fico a total disposição para dúvidas e contatos pelos emails:

ciniro@gmail.com
cinironet@zipmail.com.br

Até mais e bons projetos!

Ciniro Nametala

Ciniro Nametala - Tecnólogo em Análise e Desenvolvimento de Sistemas pelo CEFET-Bambuí. Tem artigos publicados nos principais portais e revistas nacionais de conteúdo técnico para desenvolvimento em plataforma .NET. Além de construir sistemas WEB e desktop, foi aluno bolsista do CEFET-Bambuí em parceria com a Universidade Federal de Itajubá em um projeto científico/matemático com propostas na área de engenharia elétrica para a migração de um sistema de software de VB6 para VB.NET 2005. Atualmente desenvolve projetos no departamento de computação do CEFET-Bambuí, onde atua como Técnico em Tecnologia da Informação. Espera em breve, conseguir ingressar em um programa de mestrado. (Algum orientador se dispõe?)