Recentemente eu adquiri um dispositivo IPAQ PocketPC, e depois de checar todos os aplicativos nativos, veio a idéia de criar meu primeiro programa usando o .Net Compact Framework (.Net CF).
Entre várias possibilidades, eu decidi pôr em prática uma idéia que sempre vinha à minha cabeça quando eu visitava livrarias em busca de livros técnicos importados, que é a possibilidade de checar a cotação (ou seja, o número de “estrelas”) que o livro tem no site Amazon.com, que é um bom indicativo se o livro é bom ou se é uma “bomba”.
A boa notícia é que a Amazon possui um conjunto de web services muito completo, “Amazon Web Services”(AWS), que permite checar todas as informacões relativos a livros, CDs e DVDs, bem como jogos e tudo mais que é vendido no site.
Tal aplicativo exige conexão à Internet, naturalmente, mas acredito ser uma questäo de tempo até as grandes lojas e shopping-centers no Brasil oferecerem serviço de internet wireless (Wi-Fi) para seus clientes, como já é comum nos EUA e Europa.
Apesar de ter sido escrito com .Net CF, o código que você verá abaixo é virtualmente idêntico ao que seria necessário em aplicacões ASP.Net e Windows.Forms (com excecão da interface com o usuário), e para quem não possui dispositivos móveis vale a pena lembrar que é possível usar emuladores para testar seus programas (veja como nesse ótimo artigo do site).
Vamos lá então!
1) Criando um projeto para aplicativos móveis, e adicionando a web reference à Amazon.com
O primeiro passo é criar um novo projeto no Visual Studio 2003: vamos selecionar “Smart Device Application” na janela “New Project” (dei ao projeto o nome de “Amazon”), e então “Pocket PC” para a plataforma-destino e “Windows Application” para o tipo de projeto.
Veremos então um windows.form em branco, e antes de mais nada podemos adicionar logo a web reference aos serviços da Amazon.com: na janela “Solution Explorer”, clique com o botão direito do mouse no item “References” e então selecione “Add Web Reference”. Entre o endereco para o web service, http://soap.amazon.com/schemas3/AmazonWebServices.wsdl, conforme a figura abaixo
Repare que esse servico expõe vários métodos, inclusive métodos avancados que permitem adicionar e alterar produtos no “carrinho de compras” e finalizar o pedido. Entretanto, em nosso programa nos ateremos às funções de procura. No campo “Web Reference Name”, podemos alterar o valor para AmazonWS, mais amigável.
2) Criando um ID para o Amazon Web Services
Todo programa que acessa o AWS requer um ID único, que a Amazon utiliza para identificar as chamadas. Esse ID é muito fácil de ser obtido, e é gratuito. Basta ir nessa página e seguir as instrucões. Ao fim você receberá um e-mail com uma chave de identificacão (devtag).
3) Procurando livros com o AWS
Nosso aplicativo terá 2 funções:
- Procurar títulos por palavra-chave (título, autor, ISBN, etc);
- Ver os detalhes de um título, selecionado no resultado da busca.
Vamos então adicionar um TabControl ao formulário, composto por 2 abas: no primeiro será feita a busca, no segundo veremos os detalhes do livro selecionado.
Os botões “< Ant.” e “Próx. >” permitem que o usuário navegue pelos resultados da busca sem ter que selecionar o título anterior ou posterior na primeira aba, tornando a navegacão mais cômoda, como num browser. Os demais controles adicionados são, acredito, auto-explicativos.
Terminada a interface com o usuário, podemos entrar com o código no arquivo .vb do formulário. Vamos começar pela funcão-chave de nosso código, que conecta ao web service da Amazon, e realiza busca por palavra-chave:
1 Dim products As AmazonWS.ProductInfo
2 Dim currIndex As Short
3
4 '--- essa constante eh o seu Subscription ID
5 Private Const DEVTAG = "XXXXXXXXXXXXXXXXXXXXX"
6
7 Sub SearchAmazon(ByVal str As String)
8 Cursor.Current = Cursors.WaitCursor
9
10 '---- define o parametro de busca
11 Dim keywordReq As New AmazonWS.KeywordRequest
12 With keywordReq
13 .type = "heavy"
14 .devtag = DEVTAG
15 .tag = DEVTAG
16 .mode = "books"
17 .locale = "us"
18 .sort = "reviewrank"
19 .page = 1
20 .keyword = str.Trim
21 End With
22
23 '---- conecta ao web service e realiza a busca
24 Try
25 Dim AmazWS As New AmazonWS.AmazonSearchService
26 products = AmazWS.KeywordSearchRequest(keywordReq)
27 Catch err As Exception
28 Cursor.Current = Cursors.Default
29 MsgBox(err.Message, MsgBoxStyle.Critical, "Erro na procura")
30 Exit Sub
31 End Try
32
33 '---- lista os resultados
34 If Not products Is Nothing AndAlso Not products.Details Is Nothing Then
35 For Each item As AmazonWS.Details In products.Details
36 lbResultado.Items.Add(item.ProductName)
37 Next
38 Cursor.Current = Cursors.Default
39 Else
40 Cursor.Current = Cursors.Default
41 MsgBox("Nenhum produto encontrado")
42 End If
43
44 End Sub
No topo, declaramos uma variável global à aplicacão, “products”, do tipo ProductInfo, que armazenará todos os produtos retornados pela busca.
A constante DEVTAG deverá ser preenchida com o seu Subscription ID, conforme explicado na seção 2 do artigo.
A busca no web service é feita pela funcão KeywordSearchRequest (linha 26), que recebe como parâmetro um objeto do tipo KeywordRequest que foi definido entre as linhas 11 e 21. O parâmetro “type” (linha 13) aceita 2 valores, “lite” e “heavy”, sendo que o primeiro faz que a busca retorne apenas dados básicos sobre os títulos (nome, ISBN) e o segundo traz informacões completas, tais como cotacão, preco, reviews, etc. Como uma busca pode retornar muitos títulos, o servico retorna apenas 10 de cada vez, em “páginas” de 10 itens, por razões de tráfego: para buscar mais resultados, devemos setar o parâmetro “page” (linha 19) para a página desejada. No nosso caso, estamos interessados apenas nos 10 primeiros resultados, então fixamos page=1. Finalmente, o “keyword” contém a(s) palavra(s)-chave que queremos buscar.
Agora podemos fazer o primeiro teste! Vamos entrar “vb.net” na caixa de texto e apertar “Procura”: após 2 ou 3 segundos, recebemos o resultado:
Perfeito! Agora podemos fazer o código que mostra os detalhes de um título selecionado. Os comentários no código explicam o que é feito em cada bloco.
1 Private Sub lbResultado_SelectedIndexChanged(…)
2 MostraDetalhes(lbResultado.SelectedIndex)
3 End Sub
4
5 Sub MostraDetalhes(ByVal index As Short)
6 'essa variavel controla qual item estamos vendo
7 'na lista "products"
8 currIndex = index
9
10 'desabilita o botao "< Ant" se o usuario estiver no 1o item
11 btAnterior.Enabled = (currIndex > 0)
12
13 'desabilita o botao "Prox >" se o usuario estiver no ultimo item
14 btProximo.Enabled = (currIndex < products.Details.Length - 1)
15
16 Dim currProduct As AmazonWS.Details = products.Details(currIndex)
17 With currProduct
18 lblTitulo.Text = .ProductName
19
20 'alguns titulos nao possuem informacao sobre autor,
21 'entao precisamos checar antes
22 If Not .Authors Is Nothing Then
23 lblAutor.Text = .Authors(0)
24 If .Authors.Length > 1 Then
25 lblAutor.Text &= " (et al)"
26 End If
27 Else
28 lblAutor.Text = "N/A"
29 End If
30
31 'o campo 'Reviews' tb pode eventualmente
32 'vir em branco, embora nao seja comum
33 If Not .Reviews Is Nothing Then
34 lblCotacao.Text = .Reviews.AvgCustomerRating
35 Else
36 lblCotacao.Text = "N/A"
37 End If
38
39 lblPreco.Text = .OurPrice
40 lblISBN.Text = .Isbn
41 lblDisponibilidade.Text = .Availability
42 End With
43
44 'vamos selecionar a tab com os detalhes automaticamente
45 TabControl1.SelectedIndex = 1
46 End Sub
Podemos então testar o novo código, selecionando um dos títulos retornados pela busca:
Repare que o botão Anterior está desabilitado, pois estamos vendo o primeiro item da lista (linha 11).
Agora só falta fazermos o código para os botões “Ant” e “Próx”, que é trivial:
1 Private Sub btAnterior_Click(…) Handles btAnterior.Click
2 If currIndex > 0 Then
3 MostraDetalhes(currIndex - 1)
4 End If
5 End Sub
6
7 Private Sub btProximo_Click(…) Handles btProximo.Click
8 If currIndex < products.Details.Length - 1 Then
9 MostraDetalhes(currIndex + 1)
10 End If
11 End Sub
4) Terminado o programa. Hora do “eye-candy”!
Bem, o nosso programa está pronto no que se refere a consumir os web services da Amazon.com, mas seria legal se pudéssemos também mostrar a capa dos livros, não?
Isso requer o uso da biblioteca System.Net do .Net Framework, e um trecho que código que permite salvar arquivos via HTTP. Também é bom criar uma variável do tipo Hashtable que funcionará como um cache de imagens, para que não tenhamos que baixar o mesmo arquivo duas vezes.
Então vamos adicionar um controle do tipo PictureBox na aba de detalhes, e o seguinte código:
1 Dim coverCache As New Hashtable 'guarda todas capas ja baixadas
2
3 Private Function BaixaCapa(ByVal url As String) As Image
4 If url = "" Then
5 Return Nothing
6 Else
7 'se ja temos a capa no nosso cache, podemos retorna-la diretamente
8 If coverCache.Contains(url) Then
9 Return coverCache(url)
10 Else
11 Try
12 Cursor.Current = Cursors.WaitCursor
13
14 Dim webRequest As System.Net.HttpWebRequest
15 webRequest = System.Net.HttpWebRequest.Create(url)
16 'tenta acessar por 3 segundos no maximo
17 webRequest.Timeout = 3000
18
19 Dim webResponse As System.Net.HttpWebResponse
20 webResponse = webRequest.GetResponse
21 Dim bmp As New Bitmap(webResponse.GetResponseStream)
22 webResponse.Close()
23
24 Cursor.Current = Cursors.Default
25 If Not bmp Is Nothing AndAlso bmp.Width > 1 Then
26 coverCache.Add(url, bmp)
27 Return bmp
28 Else
29 coverCache.Add(url, Nothing)
30 Return Nothing
31 End If
32 Catch e As Exception
33 Cursor.Current = Cursors.Default
34 MsgBox("Erro baixando capa:" & e.Message)
35 Return Nothing
36 End Try
37 End If
38 End If
39 End Function
Para mostrar a capa na aba de detalhes, basta adicionar o comando
1 Dim capa As Image = BaixaCapa(.ImageUrlSmall)
2 pbCapa.Image = capa
entre as linhas 41 e 42 na funcão MostraDetalhes.
Testando o nosso programa, podemos agora ver a capa, o que torna o aplicativo muito mais atraente:
Bem, um último detalhe para deixar o programa realmente legal seria trocar o campo “cotação” por estrelas, como no site da Amazon, mas isso fica como exercício para você ;-)
Espero que este artigo seja útil!
Até a próxima.