Neste post vamos implementar uma página web que atualiza o seu conteúdo sem ter de recarregar a página toda.
A estrutura básica da página tem as seguintes pastas:
\ajax - pasta com ficheiro php que pesquisa a base de dados e devolve o valor encontrado
\db - pasta com ficheiro php com instruções para ligação à base dados
\js - pasta com código javascript que utiliza a livraria JQuery para atualizar o ficheiro index.html com os dados devolvidos pelo ficheiro php que pesquisa a base de dados.
O resultado final será:
Se a página fosse construída somente com código html ao clicar no botão "Pesquisar" o browser seria redirecionado para outra página ou para a mesma mas fazendo um reload.
Para implementarmos a página sem reload utilizamos código que vai alterar o DOM da página com os dados recolhidos na base de dados.
Começamos pela página principal, index.html, com o seguinte código:
<!DOCTYPE html>
<html>
<head>
<title>AJAX Database</title>
</head>
<body>
Nome: <input type="text" id="name">
<input type="submit" id="name-submit" value="Pesquisar">
<div id="name-data"></div>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script src="js/global.js"></script>
</body>
</html>
Neste código é importante recordar os nomes do botão (name-submit), o nome do campo de introdução de texto (name) e por fim o nome da div (name-data). Estes nomes são importantes porque vamos ter de nos referir a eles no código javascript.
Antes de continuarmos vamos criar a base de dados MySQL que vai conter o dados a apresentar.
Primeiro criar a base de dados com o seguinte comando:
create database ajaxdb;
Depois criar uma tabela com nome names, assim:
create table names(name_id int,name varchar(50),location varchar(50));
Agora que temos a base de dados podemos continuar.
Olhando para o código html apresentado encontramos uma referencia a um ficheiro global.js que se encontra na pasta js. Este ficheiro vai, utilizando javascript, implementar o método post através do controlo do clique com o rato no botão.
O código javascript tem uma particularidade com a qual estou pouco à vontade que são as funções callback anónimas, desde que comecei a ver código javascript com este tipo de funções fiquei espantado! Como é que alguém consegue perceber aquilo?! Assim vou apresentar duas versões do ficheiro global.js, uma sem funções anónimas muito mais fácil de entender e outra com as funções anónimas.
Ficheiro global.js, versão sem funções anónimas:
$('input#name-submit').on('click',f_click());
function f_click(){
var name = $('input#name').val();
if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},f_recebe(data));
}
}
function f_recebe(data){
$('div#name-data').text(data);
}
A primeira linha associa a função f_click ao evento click do botão, ou seja, quando o utilizador clica no botão é chamada a dita função.
A função f_click começa por recolher o valor do campo de texto e guarda-o na variável name, como pretendemos que o valor esteja preenchido utilizamos a função trim para remover espaços em branco antes de verificar se está em branco.
Se tudo correu bem e existe um valor para pesquisar na base de dados utilizamos a função post para receber valores do servidor chamando uma página, neste caso a página name.php e passando o parâmetro name para a página. Definimos, ainda, uma função callback (f_recebe) para receber o resultado do servidor através do parâmetro data.
Dentro da função f_recebe colocamos o valor de data na div.
Antes de avançarmos para o PHP aqui fica o código da versão com funções callback anónimas:
$('input#name-submit').on('click',function(){
var name = $('input#name').val();
if($.trim(name)!=''){
$.post('ajax/name.php',{name: name},function(data){
$('div#name-data').text(data);
});
}
});
Agora o PHP, a página name.php, tem o seguinte código:
<?php
if(isset($_POST['name'])===true && empty($_POST['name'])===false){
require '../db/connect.php';
$query = mysql_query("
SELECT names.location
FROM names
WHERE names.name='".mysql_real_escape_string(trim($_POST['name']))."'
");
echo (mysql_num_rows($query)!==0) ? mysql_result($query,0,'location') : 'Nome não encontrado';
}
?>
Primeiro verificamos se o parâmetro name está preenchido, em caso afirmativo fazemos o require do ficheiro connect.php (ver código abaixo) e consultamos a base de dados com um select. O resultado da consulta é devolvido com a função echo.
O código do ficheiro connect.php é simples, estabelece a ligação à base de dados:
<?php
mysql_connect('localhost','utilizador','password');
mysql_select_db('ajaxdb');
?>
Assim temos uma página que consulta a base de dados e coloca o resultado dinamicamente na página sem recarregar a página, ao estilo gmail.
Fontes:
http://api.jquery.com/jQuery.post/
http://www.w3schools.com/jquery/jquery_syntax.asp
http://www.youtube.com/watch?v=Yb3c-HljFro
quinta-feira, 18 de abril de 2013
sábado, 13 de abril de 2013
Game of 15
Toda a gente conhece o jogo de puzzle em que existe um espaço livre para mover as peças para os lugares certos. Para quem não conhece pode sempre clicar aqui.
Hoje vamos resolver o jogo em C.
Para começar utilizamos uma matriz 4x4 para o jogo.
int jogo[4][4];
Além desta matriz vamos definir outra para armazenar a solução do jogo.
int solucao[4][4];
Antes de mais nada criamos uma função para limpar e preparar a matriz de jogo e a matriz da solução:
//prepara a matriz do jogo
void limpar(void)
{
int l,c,conta=1;
n_jogadas=0;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
jogo[l][c]=conta;
solucao[l][c]=conta;
conta++;
}
}
jogo[3][3]=0;
solucao[3][3]=0;
}
Também precisamos de uma função para mostrar o estado da matriz do jogo, assim:
//mostra a matriz do jogo
void mostrar(void)
{
int l,c;
system("cls");
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(jogo[l][c]>0){
goto_xy(10+c*3,10+l*2);
printf("%d",jogo[l][c]);
}
}
}
}
Esta função utiliza a instrução goto_xy que não existe em C mas que está definida num header file que acompanha o código fonte do projeto.
Com as duas matrizes é fácil saber se o jogo foi resolvido, basta comparar as posições de uma matriz com a outra:
//terminou?!
int resolvido(void)
{
int l,c,r=1;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(solucao[l][c]!=jogo[l][c]) r=0;
}
}
return r;
}
Como queremos que o computador resolva o jogo vamos utilizar uma tática simples, sempre que fizermos uma jogada guardamos o movimento realizado para mais tarde podermos reverter todos os movimentos até à posição inicial da matriz. Para isso vamos ter um vetor onde guardamos as jogadas e uma variável com o número de jogadas feitas.
int jogadas[100];
int n_jogadas;
Agora as funções que implementam as jogadas:
//move uma peça para a direita
void mover_direita(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c-1,l)==0) return;
temp=jogo[l][c-1];
jogo[l][c]=temp;
jogo[l][c-1]=0;
//guarda a jogada
jogadas[n_jogadas]=DIREITA;
n_jogadas++;
}
//move uma peça para a esquerda
void mover_esquerda(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c+1,l)==0) return;
temp=jogo[l][c+1];
jogo[l][c]=temp;
jogo[l][c+1]=0;
//guarda a jogada
jogadas[n_jogadas]=ESQUERDA;
n_jogadas++;
}
//move uma peça para cima
void mover_baixo(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c,l-1)==0) return;
temp=jogo[l-1][c];
jogo[l][c]=temp;
jogo[l-1][c]=0;
//guarda a jogada
jogadas[n_jogadas]=BAIXO;
n_jogadas++;
}
//move uma peça para baixo
void mover_cima(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c,l+1)==0) return;
temp=jogo[l+1][c];
jogo[l][c]=temp;
jogo[l+1][c]=0;
//guarda a jogada
jogadas[n_jogadas]=CIMA;
n_jogadas++;
}
Cada uma destas funções utiliza o seguinte algoritmo:
1. Descobrir as coordenadas do espaço livre na matriz (função pos_livre, apresentada a seguir)
2. Se as coordenadas do movimento não são válidas (função coord_validas, apresentada a seguir) não joga.
3. Guarda o número da peça a mover e troca com o 0 (zero) do espaço livre.
4. Guarda a jogada feita para mais tarde poder voltar atrás.
5. Adiciona um à variável n_jogadas.
//procura a posicao livre
void pos_livre(int &x,int &y)
{
int l,c;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(jogo[l][c]==0){
x=c;
y=l;
return;
}
}
}
}
//devolve 0 se as coordenadas estão fora da matriz
//devolve 1 se as coordenadas são válidas
int coord_validas(int x,int y)
{
if(x<0 || y<0) return 0;
if(x>3 || y>3) return 0;
return 1;
}
Para terminar o programa faltam duas funções, uma para baralhar o puzzle e outra para resolver.
Aqui ficam:
//resolve o jogo
void resolver(void)
{
int n;
for(n=n_jogadas-1;n>=0;n--){
if(jogadas[n]==ESQUERDA) mover_direita();
if(jogadas[n]==DIREITA) mover_esquerda();
if(jogadas[n]==CIMA) mover_baixo();
if(jogadas[n]==BAIXO) mover_cima();
mostrar();
Sleep(50);
}
}
//baralha
void baralhar(void)
{
int movimento,temp,sorteia;
srand(time(NULL));
for(temp=0;temp<50;temp++){
mostrar();
Sleep(50);
sorteia=rand()%4+1;
switch(sorteia){
case ESQUERDA :
mover_esquerda();
break;
case DIREITA :
mover_direita();
break;
case CIMA :
mover_cima();
break;
case BAIXO :
mover_baixo();
break;
}
}
}
Esta versão da função baralhar mostra as jogadas ao mesmo tempo que baralha isso pode ser alterado removendo a linha que chama a função mostrar().
Agora para terminar de verdade aqui fica a função main:
int main(int argc,char *argv[])
{
char op;
limpar();
baralhar();
while(1){
mostrar();
printf("\n\n\nOpcao (e,d,c,b,r):");
scanf("%c",&op);
if(op=='e') mover_esquerda();
if(op=='d') mover_direita();
if(op=='c') mover_cima();
if(op=='b') mover_baixo();
if(op=='r') resolver();
if(resolvido()) break;
}
mostrar();
system("pause");
return 1;
}
Aqui chegados só falta jogar e quando não conseguir resolver o puzzle basta escolher r.
O código fonte.
Imagem da wikipedia
Hoje vamos resolver o jogo em C.
Para começar utilizamos uma matriz 4x4 para o jogo.
int jogo[4][4];
Além desta matriz vamos definir outra para armazenar a solução do jogo.
int solucao[4][4];
Antes de mais nada criamos uma função para limpar e preparar a matriz de jogo e a matriz da solução:
//prepara a matriz do jogo
void limpar(void)
{
int l,c,conta=1;
n_jogadas=0;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
jogo[l][c]=conta;
solucao[l][c]=conta;
conta++;
}
}
jogo[3][3]=0;
solucao[3][3]=0;
}
Também precisamos de uma função para mostrar o estado da matriz do jogo, assim:
//mostra a matriz do jogo
void mostrar(void)
{
int l,c;
system("cls");
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(jogo[l][c]>0){
goto_xy(10+c*3,10+l*2);
printf("%d",jogo[l][c]);
}
}
}
}
Esta função utiliza a instrução goto_xy que não existe em C mas que está definida num header file que acompanha o código fonte do projeto.
Com as duas matrizes é fácil saber se o jogo foi resolvido, basta comparar as posições de uma matriz com a outra:
//terminou?!
int resolvido(void)
{
int l,c,r=1;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(solucao[l][c]!=jogo[l][c]) r=0;
}
}
return r;
}
Como queremos que o computador resolva o jogo vamos utilizar uma tática simples, sempre que fizermos uma jogada guardamos o movimento realizado para mais tarde podermos reverter todos os movimentos até à posição inicial da matriz. Para isso vamos ter um vetor onde guardamos as jogadas e uma variável com o número de jogadas feitas.
int jogadas[100];
int n_jogadas;
Agora as funções que implementam as jogadas:
//move uma peça para a direita
void mover_direita(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c-1,l)==0) return;
temp=jogo[l][c-1];
jogo[l][c]=temp;
jogo[l][c-1]=0;
//guarda a jogada
jogadas[n_jogadas]=DIREITA;
n_jogadas++;
}
//move uma peça para a esquerda
void mover_esquerda(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c+1,l)==0) return;
temp=jogo[l][c+1];
jogo[l][c]=temp;
jogo[l][c+1]=0;
//guarda a jogada
jogadas[n_jogadas]=ESQUERDA;
n_jogadas++;
}
//move uma peça para cima
void mover_baixo(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c,l-1)==0) return;
temp=jogo[l-1][c];
jogo[l][c]=temp;
jogo[l-1][c]=0;
//guarda a jogada
jogadas[n_jogadas]=BAIXO;
n_jogadas++;
}
//move uma peça para baixo
void mover_cima(void)
{
int l,c;
int temp;
pos_livre(c,l);
if(coord_validas(c,l+1)==0) return;
temp=jogo[l+1][c];
jogo[l][c]=temp;
jogo[l+1][c]=0;
//guarda a jogada
jogadas[n_jogadas]=CIMA;
n_jogadas++;
}
Cada uma destas funções utiliza o seguinte algoritmo:
1. Descobrir as coordenadas do espaço livre na matriz (função pos_livre, apresentada a seguir)
2. Se as coordenadas do movimento não são válidas (função coord_validas, apresentada a seguir) não joga.
3. Guarda o número da peça a mover e troca com o 0 (zero) do espaço livre.
4. Guarda a jogada feita para mais tarde poder voltar atrás.
5. Adiciona um à variável n_jogadas.
//procura a posicao livre
void pos_livre(int &x,int &y)
{
int l,c;
for(l=0;l<4;l++){
for(c=0;c<4;c++){
if(jogo[l][c]==0){
x=c;
y=l;
return;
}
}
}
}
//devolve 0 se as coordenadas estão fora da matriz
//devolve 1 se as coordenadas são válidas
int coord_validas(int x,int y)
{
if(x<0 || y<0) return 0;
if(x>3 || y>3) return 0;
return 1;
}
Para terminar o programa faltam duas funções, uma para baralhar o puzzle e outra para resolver.
Aqui ficam:
//resolve o jogo
void resolver(void)
{
int n;
for(n=n_jogadas-1;n>=0;n--){
if(jogadas[n]==ESQUERDA) mover_direita();
if(jogadas[n]==DIREITA) mover_esquerda();
if(jogadas[n]==CIMA) mover_baixo();
if(jogadas[n]==BAIXO) mover_cima();
mostrar();
Sleep(50);
}
}
//baralha
void baralhar(void)
{
int movimento,temp,sorteia;
srand(time(NULL));
for(temp=0;temp<50;temp++){
mostrar();
Sleep(50);
sorteia=rand()%4+1;
switch(sorteia){
case ESQUERDA :
mover_esquerda();
break;
case DIREITA :
mover_direita();
break;
case CIMA :
mover_cima();
break;
case BAIXO :
mover_baixo();
break;
}
}
}
Esta versão da função baralhar mostra as jogadas ao mesmo tempo que baralha isso pode ser alterado removendo a linha que chama a função mostrar().
Agora para terminar de verdade aqui fica a função main:
int main(int argc,char *argv[])
{
char op;
limpar();
baralhar();
while(1){
mostrar();
printf("\n\n\nOpcao (e,d,c,b,r):");
scanf("%c",&op);
if(op=='e') mover_esquerda();
if(op=='d') mover_direita();
if(op=='c') mover_cima();
if(op=='b') mover_baixo();
if(op=='r') resolver();
if(resolvido()) break;
}
mostrar();
system("pause");
return 1;
}
Aqui chegados só falta jogar e quando não conseguir resolver o puzzle basta escolher r.
O código fonte.
sexta-feira, 8 de março de 2013
Arduino & Motor DC
Neste post vou apresentar um pequeno projeto com o Arduino, a ideia é simples, controlar um motor DC.
O projeto vai incluir um potenciómetro para regular a velocidade do motor.
O circuito é o apresentado a seguir, criado com o fritzing.
O transistor tem 3 pernas: a base, o coletor e o emissor. A base está ligada ao pino digital do Arduino, o coletor é ligado ao motor e o emissor é ligado no neutro. O transistor além de funcionar como interruptor, ligado e desligado o motor, vai funcionar como um acelerador pois quanto maior o valor da base maior a corrente que flui entre o emissor e o coletor.
Antes de definir a velocidade do motor o Arduino lê o valor do potenciómetro, ajusta a escala, no potenciómetro vai de 0 a 1023, para um valor entre 0 e 255 e depois envia esse valor para a porta onde a base do transistor está ligada.
A porta do potenciómetro é analógica o que permite ler valores entre 0 e 1023.
Por outro lado a porta do transistor é digital e a variação da velocidade é conseguida através da técnica PWM - Pulse With Modulation.
Por fim temos de ligar o Arduino à terra da pilha de 9V.
O código fica assim:
Primeiro as constantes e as variáveis
const int potPin=0; //pino onde o potenciometro fica ligado
const int transistorPin=9; //pino onde fica ligado o transistor
int potValue=0; //valor lido do potenciometro
Depois a função setup (é executada uma vez quando o programa arranca)
void setup(){
pinMode(transistorPin,OUTPUT);
Serial.begin(9600);
}
Por fim o ciclo (Repetido eternamente)
void loop(){
potValue=analogRead(potPin)/4;
analogWrite(transistorPin,potValue);
Serial.println(potValue);
}
Além do código que lê os valores do potenciómetro e escreve para a porta do transistor incluí código para debug, enviando os valores para o computador através do cabo USB.
E a magia acontece...
Mas, sim tem um mas, o motor só pode rodar numa direção.
É um projeto simples mas que pode ser reutilizado para energias maiores, dependendo dos valores que o transistor suportar.
Por segurança incluí um diodo para proteger o Arduino de eventuais descargas que o motor possa gerar quando pára.
Projeto para download.
quinta-feira, 28 de fevereiro de 2013
CalcNotas - WindowsPhone
Para este post vamos desenvolver uma aplicação, ou como se dizia antigamente um programa, para calcular notas finais de uma disciplina do ensino secundário português.
Como a interface é relativamente grande precisamos de permitir deslocar o conteúdo verticalmente.
Para validar os dados nas textboxes vamos criar uma função que implementa a função isNumeric da versão desktop do Visual Basic.
Public Function isNumeric(ByVal str As String) As Boolean
Dim t As Decimal = 0
Return Decimal.TryParse(str, t)
End Function
Se a string poder ser convertida num número devolve true se não devolve false.
O primeiro botão serve para calcular a chamada CIF (Classificação Interna Final) que corresponde à média das notas do 10º, do 11º e do 12º ano.
Para isso temos de verificar se cada textbox tem um valor numérico caso contrário não consideramos o seu conteúdo.
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim n10, n11, n12, media, exame, conta As Integer
Dim notamin As Double
If isnumeric(Me.tb_nota10.Text) = True Then
n10 = Me.tb_nota10.Text
conta = 1
End If
If isnumeric(Me.tb_nota11.Text) = True Then
n11 = Me.tb_nota11.Text
conta = conta + 1
End If
If isnumeric(Me.tb_nota12.Text) = True Then
n12 = Me.tb_nota12.Text
conta = conta + 1
End If
If conta = 0 Then
MessageBox.Show("Tem de introduzir pelo menos uma nota!")
Exit Sub
End If
media = (n10 + n11 + n12) / conta
Me.lb_media.Text = media
notamin = media * 0.7
For exame = 1 To 20
If notamin + exame * 0.3 >= 9.5 Then
Exit For
End If
Next
Me.tb_exame.Text = exame
End Sub
O segundo botão calcula a CFD (classificação Final da Disciplina).
Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click
Dim cif, exame, cfd As Integer
If isnumeric(lb_media.Text) = False Then
MessageBox.Show("Calcule primeiro a CIF")
Exit Sub
End If
If isnumeric(tb_nota_exame.Text) = False Then
MessageBox.Show("Indique a nota do exame!")
Exit Sub
End If
cif = lb_media.Text
exame = tb_nota_exame.Text
cfd = cif * 0.7 + exame * 0.3
Me.tb_cfd.Text = cfd
End Sub
O terceiro botão guarda a CFD na listbox.
Private Sub Button3_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button3.Click
If isnumeric(Me.tb_cfd.Text) = False Then
MessageBox.Show("Calcule primeiro a CFD!")
Exit Sub
End If
Me.ListBox1.Items.Add(Me.tb_cfd.Text)
End Sub
Por fim temos uma hiperligação que permite abrir uma página da net.
Private Sub HyperlinkButton1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles HyperlinkButton1.Click
Dim pagina As WebBrowserTask = New WebBrowserTask()
pagina.Uri = New Uri("http://alunosnet.pt.vu", UriKind.Absolute)
pagina.Show()
End Sub
Projeto para download
Como a interface é relativamente grande precisamos de permitir deslocar o conteúdo verticalmente.
Para validar os dados nas textboxes vamos criar uma função que implementa a função isNumeric da versão desktop do Visual Basic.
Public Function isNumeric(ByVal str As String) As Boolean
Dim t As Decimal = 0
Return Decimal.TryParse(str, t)
End Function
Se a string poder ser convertida num número devolve true se não devolve false.
O primeiro botão serve para calcular a chamada CIF (Classificação Interna Final) que corresponde à média das notas do 10º, do 11º e do 12º ano.
Para isso temos de verificar se cada textbox tem um valor numérico caso contrário não consideramos o seu conteúdo.
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Dim n10, n11, n12, media, exame, conta As Integer
Dim notamin As Double
If isnumeric(Me.tb_nota10.Text) = True Then
n10 = Me.tb_nota10.Text
conta = 1
End If
If isnumeric(Me.tb_nota11.Text) = True Then
n11 = Me.tb_nota11.Text
conta = conta + 1
End If
If isnumeric(Me.tb_nota12.Text) = True Then
n12 = Me.tb_nota12.Text
conta = conta + 1
End If
If conta = 0 Then
MessageBox.Show("Tem de introduzir pelo menos uma nota!")
Exit Sub
End If
media = (n10 + n11 + n12) / conta
Me.lb_media.Text = media
notamin = media * 0.7
For exame = 1 To 20
If notamin + exame * 0.3 >= 9.5 Then
Exit For
End If
Next
Me.tb_exame.Text = exame
End Sub
O segundo botão calcula a CFD (classificação Final da Disciplina).
Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click
Dim cif, exame, cfd As Integer
If isnumeric(lb_media.Text) = False Then
MessageBox.Show("Calcule primeiro a CIF")
Exit Sub
End If
If isnumeric(tb_nota_exame.Text) = False Then
MessageBox.Show("Indique a nota do exame!")
Exit Sub
End If
cif = lb_media.Text
exame = tb_nota_exame.Text
cfd = cif * 0.7 + exame * 0.3
Me.tb_cfd.Text = cfd
End Sub
O terceiro botão guarda a CFD na listbox.
Private Sub Button3_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button3.Click
If isnumeric(Me.tb_cfd.Text) = False Then
MessageBox.Show("Calcule primeiro a CFD!")
Exit Sub
End If
Me.ListBox1.Items.Add(Me.tb_cfd.Text)
End Sub
Por fim temos uma hiperligação que permite abrir uma página da net.
Private Sub HyperlinkButton1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles HyperlinkButton1.Click
Dim pagina As WebBrowserTask = New WebBrowserTask()
pagina.Uri = New Uri("http://alunosnet.pt.vu", UriKind.Absolute)
pagina.Show()
End Sub
Projeto para download
sexta-feira, 8 de fevereiro de 2013
RFID Tags
As etiquetas RFID são, hoje em dia, muito comuns em diversas atividades, desde cartões de identificação a etiquetas para identificar produtos.
RFID significa Radio Frequency Identification (Identificação por rádio frequência).
O principio é simples, existe um leitor e uma etiqueta que comunicam, mas ao contrário dos rádios a etiqueta não tem de ser alimentada (apesar de existirem algumas que são) por baterias, esta é alimentada pelo leitor por um período breve de tempo durante o qual é enviado para o leitor o número de identificação da etiqueta.
Para este pequeno projeto vou utilizar uma placa RFID USB da SparkFun para comunicar com um leitor RFID.
O leitor encaixa na placa que por sua vez liga-se ao computador via USB. Nada mais fácil.
Agora precisamos dos drivers da placa para isso basta seguir este link.
Depois do dispositivo estar instalado temos de saber qual o número da porta que lhe foi atribuído para isso basta ir ao gestor de dispositivos e procurar na secção portas.
No meu caso é a porta COM31.
Agora vamos até ao Visual Basic fazer um pequeno programa para ler as etiquetas.
No formulário vamos utilizar o componente SerialPort para receber do leitor RFID os dados das etiquetas.
Agora o código.
Primeiro o botão que atualiza a porta de comunicação e abre a porta.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If Me.SerialPort1.IsOpen = True Then Me.SerialPort1.Close()
Try
Me.SerialPort1.PortName = Me.TextBox1.Text
If Me.SerialPort1.IsOpen = False Then Me.SerialPort1.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Agora o componente SerialPort, por defeito este já está configurado para um baud rate de 9600 que é a mesma velocidade da placa da SparkFun, como já deve ter percebido esta porta apesar de ser usb utiliza um protocolo de comunicação série tal como o arduino.
Para ler os dados da SerialPort adicionamos um timer que quando detetar dados lê-os e adiciona-os à listbox, o código do timer:
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim letra As Char
Static texto As String
If Me.SerialPort1.IsOpen = False Then Exit Sub
letra = ChrW(Me.SerialPort1.ReadChar())
If Char.IsLetterOrDigit(letra) Then
texto = texto & letra
Else
If texto = "" Then Exit Sub
If texto <> "" Then
Me.ListBox1.Items.Add(texto)
texto = ""
End If
End If
End Sub
Com este código cada letra da tag é lida individualmente e adicionada à string quando a letra lida não é válida verificamos se terminamos de ler para adicionar à listbox.
O projeto pode ser encontrado aqui.
RFID significa Radio Frequency Identification (Identificação por rádio frequência).
O principio é simples, existe um leitor e uma etiqueta que comunicam, mas ao contrário dos rádios a etiqueta não tem de ser alimentada (apesar de existirem algumas que são) por baterias, esta é alimentada pelo leitor por um período breve de tempo durante o qual é enviado para o leitor o número de identificação da etiqueta.
Para este pequeno projeto vou utilizar uma placa RFID USB da SparkFun para comunicar com um leitor RFID.
O leitor encaixa na placa que por sua vez liga-se ao computador via USB. Nada mais fácil.
Agora precisamos dos drivers da placa para isso basta seguir este link.
Depois do dispositivo estar instalado temos de saber qual o número da porta que lhe foi atribuído para isso basta ir ao gestor de dispositivos e procurar na secção portas.
No meu caso é a porta COM31.
Agora vamos até ao Visual Basic fazer um pequeno programa para ler as etiquetas.
No formulário vamos utilizar o componente SerialPort para receber do leitor RFID os dados das etiquetas.
Agora o código.
Primeiro o botão que atualiza a porta de comunicação e abre a porta.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If Me.SerialPort1.IsOpen = True Then Me.SerialPort1.Close()
Try
Me.SerialPort1.PortName = Me.TextBox1.Text
If Me.SerialPort1.IsOpen = False Then Me.SerialPort1.Open()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Agora o componente SerialPort, por defeito este já está configurado para um baud rate de 9600 que é a mesma velocidade da placa da SparkFun, como já deve ter percebido esta porta apesar de ser usb utiliza um protocolo de comunicação série tal como o arduino.
Para ler os dados da SerialPort adicionamos um timer que quando detetar dados lê-os e adiciona-os à listbox, o código do timer:
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
Dim letra As Char
Static texto As String
If Me.SerialPort1.IsOpen = False Then Exit Sub
letra = ChrW(Me.SerialPort1.ReadChar())
If Char.IsLetterOrDigit(letra) Then
texto = texto & letra
Else
If texto = "" Then Exit Sub
If texto <> "" Then
Me.ListBox1.Items.Add(texto)
texto = ""
End If
End If
End Sub
Com este código cada letra da tag é lida individualmente e adicionada à string quando a letra lida não é válida verificamos se terminamos de ler para adicionar à listbox.
O projeto pode ser encontrado aqui.
sexta-feira, 25 de janeiro de 2013
Vamos acelerar
Como é do conhecimento geral os telemóveis Android têm um sensor designado de acelerómetro.
Este sensor permite avaliar os movimentos a que o dispositivo está sujeito num sistema de três eixos.
O eixo dos x permite avaliar a inclinação do dispositivo para a esquerda ou para a direita. O eixo dos y é controlado pela inclinação do dispositivo para a frente ou para trás. O eixo dos z reflete o movimento para cima e para baixo.
Para este pequeno projeto vamos fazer um labirinto cujo objetivo é levar uma esfera até ao buraco inclinando o dispositivo tal como se se trata-se um jogo físico.
Primeiro vamos criar um projeto novo.
Na atividade principal (MainActivity) vamos implementar uma função que fica associada ao sensor, é o que se designa por SensorEventListener.
Assim alteramos a declaração da class para
public class MainActivity extends Activity implements SensorEventListener{
De seguida na função onCreate temos de "capturar" o sensor, para isso criamos um objeto SensorManager e outro objeto Sensor.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this,mSensor,SensorManager.SENSOR_DELAY_NORMAL);
Posto isto temos de implementar a função onSensorChanged, que vai receber os valores do sensor sempre que este sofrer alterações.
public void onSensorChanged(SensorEvent event) {
//recolher os três valores para as variáveis
x=event.values[0];
y=event.values[1];
z=event.values[2];
}
Com estas funções implementadas vamos passar à fase gráfica, para implementar a interface vamos utilizar uma ImageView que depois associamos ao xml do layout do programa.
Vamos, então, adicionar uma class nova que vai implementar a lógica e os gráficos.
public class ecran extends ImageView{
Nesta class vamos implementar a função onSizeChanged que vai permitir saber o tamanho do ecrã, para, em função desse tamanho, implementarmos as paredes do labirinto.
Precisamos, ainda, da função onDraw, que além de desenhar tudo no ecrã vai calcular a posição da esfera em função dos valores do sensor. Como o sensor é controlado na MainActivity é necessário implementar três métodos públicos na MainActivity para podermos aceder aos valores do sensor.
Primeiro um método que nos dá a instancia atual.
public static MainActivity getInstance(){
return instance;
}
Este método vai permitir à class ecran, que é a que desenha no ecrã do dispositivo, ter acesso aos outros dois métodos, um que devolve o valor x e outro para o valor y do sensor.
public float getX()
{
return x;
}
public float getY()
{
return y;
}
No projeto também está implementado o método para o z mas não é utilizado.
Para as paredes do labirinto criei um vetor de retângulos.
As paredes são definidas por código e desenhadas com a cor vermelha.
A função principal é a onDraw que trata de:
1º desenhar o buraco de saída do labirinto.
2º desenhar as paredes.
3º receber os valores da inclinação do dispositivo.
4º calcular a nova posição da esfera calculado se esta bate em alguma parede.
5º se a esfera está suficientemente perto do buraco para declarar vitória.
Por fim o layout da atividade que fica assim:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#FFFFFF">
<edu.pjcferreira.labirinto.ecran
android:id="@+id/ecran"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
É um layout linear que associa a class ecran ao ecrã.
Em resumo: este projeto demonstra como desenhar no ecrã utilizando as funções gráficas do sistema operativo Android, desde imagens a figuras geométricas bem como escrever texto e ainda a utilização do sensor acelerómetro.
O projeto e a aplicação.
sexta-feira, 4 de janeiro de 2013
i-Racer
Neste post vamos criar um programa que permite controlar um i-Racer com um dispositivo Android através do Bluetooth.
Para quem ainda não conhece este pequeno carro fica aqui um vídeo.
O i-Racer responde a um conjunto limitado de comandos em hexadecimal cujo significado pode ser encontrado aqui.
O objetivo é demonstrar o funcionamento do envio dos comandos através do Bluetooth, para isso vamos implementar quatro comandos: andar para a frente, andar para trás, virar rodas para direita e virar rodas para a esquerda. Os restantes comandos são igualmente fáceis de implementar basta alterar os códigos enviados ao i-Racer.
Para começar a interface.
O design:
Em execução:
Resumindo:
- oito botões;
- duas listviews, uma onde estão os botões a outra para apresentar os dispositivos Bluetooth emparelhados e detetados.
O xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginTop="4dp"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onLigarClick"
android:text="@string/ligar" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onProcurarClick"
android:text="@string/procurar" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onAbrirClick"
android:text="@string/abrir" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginTop="58dp"
android:orientation="horizontal" >
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onFrenteClick"
android:text="@string/frente" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onPararClick"
android:text="@string/parar" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onEsquerdaClick"
android:text="@string/esquerda" />
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onDireitaClick"
android:text="@string/direita" />
<Button
android:id="@+id/button8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSairClick"
android:text="@string/sair" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/linearLayout1"
android:layout_marginLeft="0dp"
android:layout_marginTop="82dp"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
</RelativeLayout>
Agora uma classe para controlar as comunicações. Os tutoriais da google sobre o Bluetooth do Android são muito completos mas também algo complexos, ainda que isso seja normal quando estamos a criar programas de comunicação entre dispositivos.
Para este pequeno dispositivo nós só temos de enviar os comandos não temos de receber, assim a classe criada permite abrir um canal de comunicação, estabelecer uma ligação, enviar dados, devolver o estado da ligação e terminar a ligação.
O código é algo complexo mas está comentado e envia mensagens para o Log de modo que a que seja mais fácil fazer o debug da aplicação.
package edu.pjcferreira.btremote;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
public class ConnectThread extends Thread{
private BluetoothAdapter mBluetoothAdapter;//dispositivo local
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice; //dispositivo remoto
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //para ligar a uma board serial tem que ser com este UUID
private int estado;
private OutputStream mmOutStream=null;
//recebe o dispositivo remoto ao qual ligar
public ConnectThread(BluetoothDevice device){
BluetoothSocket tmp=null;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mmDevice=device;
estado=-1;
try{
Log.d("BT","Abre o canal de ligação");
tmp=mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket=tmp;
estado=0;
Log.d("BT","Canal aberto!");
}catch(IOException e){
estado=-1;
}
}
//método para enviar os comandos
public void enviar(byte x){
if (mmOutStream==null){
try{
mmOutStream=mmSocket.getOutputStream();
}catch(IOException e){
return;
}
}
try{
mmOutStream.write(x);
}catch(IOException ee){
return;
}
Log.d("BT","ENVIADO COM SUCESSO!");
}
//função que devolve o estado da ligação
public String getEstado(){
return Integer.toString(estado);
}
//estabelece a ligação
public void run(){
mBluetoothAdapter.cancelDiscovery();
try{
mmSocket.connect();
Log.d("BT","LIGADO");
estado=1;
}catch(IOException connectException){
try{
mmSocket.close();
Log.d("BT","ERRO A LIGAR");
estado=-1;
}catch(IOException closeException){}
}
return;
}
//termina a ligação
public void cancel(){
try{
mmSocket.close();
estado=-1;
}catch(IOException e){}
}
}
Para quem ainda não conhece este pequeno carro fica aqui um vídeo.
O i-Racer responde a um conjunto limitado de comandos em hexadecimal cujo significado pode ser encontrado aqui.
O objetivo é demonstrar o funcionamento do envio dos comandos através do Bluetooth, para isso vamos implementar quatro comandos: andar para a frente, andar para trás, virar rodas para direita e virar rodas para a esquerda. Os restantes comandos são igualmente fáceis de implementar basta alterar os códigos enviados ao i-Racer.
Para começar a interface.
O design:
Em execução:
Resumindo:
- oito botões;
- duas listviews, uma onde estão os botões a outra para apresentar os dispositivos Bluetooth emparelhados e detetados.
O xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginTop="4dp"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onLigarClick"
android:text="@string/ligar" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onProcurarClick"
android:text="@string/procurar" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onAbrirClick"
android:text="@string/abrir" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="false"
android:layout_alignParentTop="true"
android:layout_centerInParent="true"
android:layout_marginTop="58dp"
android:orientation="horizontal" >
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onFrenteClick"
android:text="@string/frente" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onPararClick"
android:text="@string/parar" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onEsquerdaClick"
android:text="@string/esquerda" />
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onDireitaClick"
android:text="@string/direita" />
<Button
android:id="@+id/button8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSairClick"
android:text="@string/sair" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/linearLayout1"
android:layout_marginLeft="0dp"
android:layout_marginTop="82dp"
android:orientation="vertical" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
</RelativeLayout>
Agora uma classe para controlar as comunicações. Os tutoriais da google sobre o Bluetooth do Android são muito completos mas também algo complexos, ainda que isso seja normal quando estamos a criar programas de comunicação entre dispositivos.
Para este pequeno dispositivo nós só temos de enviar os comandos não temos de receber, assim a classe criada permite abrir um canal de comunicação, estabelecer uma ligação, enviar dados, devolver o estado da ligação e terminar a ligação.
O código é algo complexo mas está comentado e envia mensagens para o Log de modo que a que seja mais fácil fazer o debug da aplicação.
package edu.pjcferreira.btremote;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
public class ConnectThread extends Thread{
private BluetoothAdapter mBluetoothAdapter;//dispositivo local
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice; //dispositivo remoto
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //para ligar a uma board serial tem que ser com este UUID
private int estado;
private OutputStream mmOutStream=null;
//recebe o dispositivo remoto ao qual ligar
public ConnectThread(BluetoothDevice device){
BluetoothSocket tmp=null;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mmDevice=device;
estado=-1;
try{
Log.d("BT","Abre o canal de ligação");
tmp=mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
mmSocket=tmp;
estado=0;
Log.d("BT","Canal aberto!");
}catch(IOException e){
estado=-1;
}
}
//método para enviar os comandos
public void enviar(byte x){
if (mmOutStream==null){
try{
mmOutStream=mmSocket.getOutputStream();
}catch(IOException e){
return;
}
}
try{
mmOutStream.write(x);
}catch(IOException ee){
return;
}
Log.d("BT","ENVIADO COM SUCESSO!");
}
//função que devolve o estado da ligação
public String getEstado(){
return Integer.toString(estado);
}
//estabelece a ligação
public void run(){
mBluetoothAdapter.cancelDiscovery();
try{
mmSocket.connect();
Log.d("BT","LIGADO");
estado=1;
}catch(IOException connectException){
try{
mmSocket.close();
Log.d("BT","ERRO A LIGAR");
estado=-1;
}catch(IOException closeException){}
}
return;
}
//termina a ligação
public void cancel(){
try{
mmSocket.close();
estado=-1;
}catch(IOException e){}
}
}
Agora com esta classe podemos iniciar a comunicação mas primeiro precisamos de verificar se o dispositivo tem Bluetooth, isso é feito na função onCreate que se apresenta a seguir.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//verifica se existe bt neste dispositivo
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter==null){
showMessage("Não tem suporte para bluetooth!");
}else{
showMessage("Tem suporte para bluetooth!");
}
//lista de dispositivos
mArrayAdapter = new ArrayAdapter<String>(this,R.layout.simplerow,0);
//registar a função que vai receber os dispositivos encontrados
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//tambem recebe a mensagem que terminou a pesquisa
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
//lista de dispositivos
listView = (ListView) findViewById(R.id.listView1);
}
Esta função também regista uma função callback para que quando os dispositivos Bluetooth são encontrados poderem ser adicionados à listview. O código dessa função é este:
private final BroadcastReceiver mReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
showMessage(device.getName());
}else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
// showMessage("Terminado! Encontrados " + mArrayAdapter.getCount() + " dispositivos!");
listView.setAdapter(mArrayAdapter);
listView.setClickable(true);
//função a chamar quando clicar num item da lista
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
Object o = listView.getItemAtPosition(position);
showMessage("Selecionou " + o.toString());
//tenta ligar ao dispositivo
dispositivo=position;
String[] endereco=o.toString().split("\n");
/* showMessage(endereco[0]);
showMessage(endereco[1]);*/
remoteBluetoothDevice= mBluetoothAdapter.getRemoteDevice(endereco[1]);
}
});
}
}
};
De seguida precisamos de uma função para pesquisar dispositivos Bluetooth, quer os que estão emparelhados quer outros:
public void onProcurarClick(View botton) {
//primeiro vamos procurar dispositivos emparelhados
pairedDevices=mBluetoothAdapter.getBondedDevices();
//se existem
if(pairedDevices.size()>0){
for(BluetoothDevice device : pairedDevices){
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
showMessage(device.getName());
}
}
//procurar novos dispositivos
mBluetoothAdapter.startDiscovery();
}
Posto isto podemos abrir uma ligação com o dispositivo selecionado:
public void onAbrirClick(View botton) {
if(remoteBluetoothDevice==null){
showMessage("Primeiro deve selecionar o dispositivo!");
return;
}
ligacao=new ConnectThread(remoteBluetoothDevice);
ligacao.run();
showMessage(ligacao.getEstado());
}
Agora podemos enviar os comandos, para isso temos uma função para cada comando:
public void onFrenteClick(View botton) {
byte x;
x=0x1B;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
ligacao.enviar(x);
}
public void onEsquerdaClick(View botton) {
byte x;
x=0x36;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
ligacao.enviar(x);
}
public void onDireitaClick(View botton) {
byte x;
x=0x46;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
ligacao.enviar(x);
}
public void onPararClick(View botton){
byte x;
x=0x00;
if(ligacao==null){
showMessage("Primeiro tem de abrir uma ligação.");
return;
}
ligacao.enviar(x);
}
Antes de terminarmos precisamos de limpar a casa, o botão sair e ainda a função onDestroy:
public void onSairClick(View botton) {
byte x;
x=0x00;
if(ligacao!=null){
ligacao.enviar(x);
ligacao.cancel();
}
finish();
}
protected void onDestroy() {
byte x;
x=0x00;
if(ligacao!=null){
ligacao.enviar(x);
ligacao.cancel();
}
this.unregisterReceiver(mReceiver);
super.onDestroy();
}
Quase me esquecia as permissões, neste projeto precisamos de duas:
- Permissão para utilizar Bluetooth:
<uses-permission android:name="android.permission.BLUETOOTH"/>
- Permissão para pesquisar dispositivos com o Bluetooth:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Subscrever:
Mensagens (Atom)














