conexão bluetooth android

Upload: lincoln-vasconcelos

Post on 18-Jul-2015

2.492 views

Category:

Documents


3 download

DESCRIPTION

comunicação android

TRANSCRIPT

Conexo Bluetooth Android Parte 01: Estrutura InicialOl! Esta a primeira parte de um artigo sobre como desenvolver uma conexo entre um computador utilizando Java e um dispositivo Android. Java? Sim, Java. Eu no posso negar que gosto e admiro algumas caractersticas da linguagem e sua estruturao.

ApresentaoEste artigo no vai explicar o que uma conexo Bluetooth ou quais as camadas de rede ela utiliza. Basicamente, vamos ver como podemos criar um servidor Bluetooth em qualquer mquina que possua instalado uma JRE e possivelmente algumas bibliotecas externas, como a BlueZ no Ubuntu. Aps, ser apresentado como criar um pequeno aplicativo que conecte neste servidor no Android. Tambm informo que alguns dados esto em ingls, principalmente porque meu Sistema Operacional foi instalado nesta linguagem e que meu Sistema Operacional o Ubuntu 11.04 Natty Narwhal. Estou utilizando o Eclipse Indigo para desenvolvimento e a verso do Java a 1.6.0_26.

IntroduoO presente documento resultado da pesquisa de como criar um Apresentador de Slides para Android que utilize uma conexo Bluetooth com uma mquina local, fruto da disciplina de Programao para Dispositivos Mveis do primeiro semestre do ano atual. O Java no possui uma biblioteca nativa para conexo Bluetooth, somente uma especificao, possivelmente para manter a portabilidade. Portabilidade define as caractersticas que uma linguagem de programao possui semelhantes entre vrias arquiteturas de computador, como o tamanho de memria para alocar determinado tipo de dado. Ora, se o Java sempre utiliza a mesma mquina virtual para ser executado, porque ele considerado uma linguagem portvel?

Bibliotecas NecessriasAlm de um bom ambiente de desenvolvimento, vamos precisar de algumas bibliotecas adicionais ao Java para criar uma conexo Bluetooth na mquina local. Obviamente, voc tambm ir precisar de um trasmissor Bluetooth devidamente instalado. Vamos utilizar a biblioteca Bluecove para criar um servio de conexo Bluetooth. Tambm vamos utilizar para desenvolvimento o ambiente Eclipse, mas tambm ser possvel a utilizao de outras interfaces, como Netbeans. Simplesmente devemos efetuar o download de dois arquivo JAR que possuem a biblioteca Bluecove. Quando este artigo foi desenvolvido, a verso atual era a 2.1.0 e pode ser adquirida acessando a pgina oficial do Bluecove no SourceForge. Voc vai precisar dos arquivos, o bluecove-2.1.0.jar e bluecove-gpl-2.1.0.jar.

1

Particularmente, acho interessante que coloque estes arquivos num diretrio especial, dentro de seu home. Eu vou armazen-los dentro do diretrio ~/Apps/jars.

Novo ProjetoVamos criar um novo projeto Java no Eclipse com o nome BluetoothServer. Acesse as propriedades do projeto atravs do menu File - Properties, entre no menu Java Build Path. Acesse a aba Libraries e adicione os arquivos JAR do Bluecove acessando a opo Add External JAR, conforme o exemplo abaixo.

Propriedades do Projeto com Bluecove Agora vamos criar uma pequena classe de exemplo que ir trabalhar como um servidor Bluetooth e que poder receber uma conexo de qualquer outro dispositivo.

Estrutura InicialVamos adicionar uma nova classe chamada Server com um nome de pacote qualquer. Neste caso, o pacote utilizado ser o endereo oficial do autor. Aps, vamos tornar a classe executvel implementando a interface Runnable. O mtodo run receber a lgica de abertura de conexo. Tambm vamos adicionar um mtodo principal main para abertura do servio. Teremos a seguinte estrutura de classe.package br.nom.camargo.wanderson.bluetooth.server; /** * Servidor Bluetooth * @author Wanderson Henrique Camargo Rosa */ public class Server implements Runnable { /** * Fluxo de Execuo Principal */ public void run() { // Servio de Conexo Bluetooth } /** * Execuo Principal do Aplicativo * @param args Argumentos de Execuo */

2

public static void main(String args[]) { Server server = new Server(); server.run(); } }

Com esta estrutura inicial, vamos criar um servidor capaz de receber uma conexo Bluetooth atravs de qualquer outro dispositivo. O servidor ser desenvolvido no prximo artigo desta sequncia, interno ao mtodo run.

Consideraes FinaisO desenvolvimento de aplicativos para dispositivos mveis muito interessante, principalmente usufruindo dos recursos internos destes, como acelermetro e GPS. Com a necessidade de compra de um Apresentador de Slides para utilizao em palestras e seminrios, tive a idia de criar um aplicativo que enviasse informaes de um Android para a mquina local, onde esta iria processar a solicitao e navegar no documento que est sendo exibido atualmente. Uma pequena idia que tem muito utilidade. Este o primeiro documento da srie sobre como criar uma conexo Bluetooth entre dispositivo Android e um computador, utilizando Java e Bluecove. Voc pode conferir o desenvolvimento do servidor Bluetooth no prximo artigo.

Conexo Bluetooth Android Parte 02: ServidorEste artigo pertence sequncia sobre como criar uma conexo Bluetooth entre Android e um computador local, utilizando Java e a biblioteca Bluecove. Anteriormente foi apresentado como configuramos o Eclipse para o novo projeto com esta biblioteca utilizando arquivos JAR. Ao final, foi apresentada uma pequena estrutura de classe Server, onde ser desenvolvido o servidor Bluetooth. Neste momento vamos ver como abrir um servio Bluetooth na mquina local para que qualquer dispositivo efetue uma conexo, neste caso um Android.

Informaes IniciaisA primeira coisa que devemos fazer configurar um identificador nico de conexo para a conexo que ser feita. Este identificador uma sequncia de caracteres que considerada quase que impossvel de ser gerada em dois aplicativos diferentes. Voc encorajado a gerar outro valor, diferente do exemplo abaixo. Exemplificando, este valor ir trabalhar como o nmero da porta utilizada em conexes TCP/IP. Vale ressaltar que este valor no pode conter nenhum trao, porque a biblioteca no identifica a sequncia como vlida.

3

Para abertura de servio, vamos utilizar o btspp, onde podemos trabalhar com entrada e sada de fluxos de dados, os famosos InputStream e OutputStream. Esta configurao inicial tem o seguinte formato.public void run() { // Identificador nico de Conexo String uuid = "879c3537-ae66-4013-a677-9b7e5339d13c"; // Endereo para Conexo String address = "btspp://localhost:" + uuid.replace("-", ""); }

Vamos agora abrir o servio com as informaes configuradas previamente, utilizando as classes disponibilizadas pela biblioteca Bluecove.

Abertura de ServioExiste uma classe chamada StreamConnectionNotifier que fornece o notificador de conexes. Este notificador criado utilizando um padro de projeto Factory da classe Connector. Para isto, basta informar o endereo de abertura de conexo ao conector e este criar um objeto do tipo notificador. Comparando novamente com uma conexo TCP/IP, o notificador pode ser considerado como a classe ServerSocket utilizada pelo Java para esperar uma conexo do cliente. Aps a criao do notificador, vamos acessar o mtodo bloqueante acceptAndOpen. Isto quer dizer que o programa estar travado neste ponto at que uma conexo cliente entre ou at que seja finalizado. Obviamente, voc deve tratar os erros gerados devidamente, tornando o cdigo mais seguro. O mtodo acessado ir retornar um objeto da classe StreamConnection que trabalha da mesma forma que um socket na conexo TCP/IP. Temos o seguinte cdigo atualmente.public void run() { // Identificador nico de Conexo String uuid = "879c3537-ae66-4013-a677-9b7e5339d13c"; // Endereo para Conexo String address = "btspp://localhost:" + uuid.replace("-", ""); try { // Abertura de Conexo StreamConnectionNotifier notifier = (StreamConnectionNotifier) Connector.open(address); // Fluxo de Conexo StreamConnection stream = notifier.acceptAndOpen(); } catch (IOException e) { // Erro Encontrado e.printStackTrace(); } }

Lembre-se que os mtodos atiram excees e neste local somos obrigados a criar um bloco de manipulao de erros do tipo try..catch. Agora podemos capturar os fluxos de entrada e sada de dados e trabalhar como qualquer tipo de leitura e escrita.

4

Fluxos de Entrada e SadaO Java possui classes para manipulao de dados, com mtodos para tratamento de entrada e sada de informaes. Podemos solicitar ao objeto do tipo StreamConnection estes fluxos da seguinte forma. Lembre-se que este cdigo ainda pertence a estrutura do exemplo anterior e, ao final deste artigo, a classe completa ser apresentada.// Fluxo de Conexo StreamConnection stream = notifier.acceptAndOpen(); // Captura de Fluxos InputStream input = stream.openInputStream(); OutputStream output = stream.openOutputStream();

Podemos trabalhar como qualquer outro fluxo do Java. Para exemplificar, vamos criar um lao de repetio que exibe na sada padro da mquina local uma sequncia de dados enviada pelo cliente. Este lao ser exibido at que o cliente fornea a palavra SAIR ou at que a conexo seja finalizada, gerando uma exceo capturada no bloco try..catch. Durante a execuo do lao, precisamos adicionar informaes de controle ou um pequeno protocolo para transferncia dos dados. Este protocolo possui uma pequena regra: primeiramente deve ser enviado um inteiro contendo quantos bytes sero enviados e aps estes devem ser fornecidos.// Lao de Repetio int size; byte content[]; // Auxiliares de Leitura String message = ""; // Mensagem Enviada pelo Cliente while (!message.equals("SAIR")) { // Tamanho dos Dados size = input.read(); // Quantidade de Bytes // Buffer de Leitura content = new byte[size]; // Preenchimento dos Dados input.read(content); // Entrada de Informao // Transformao da Mensagem Enviada message = new String(content); // Novo Elemento // Exibio na Sada Padro System.out.println(message); }

Primeiramente h a inicializao de variveis que sero utilizadas pelo lao de repetio, auxiliando na leitura do fluxo de entrada de dados. Aps, o lao executado at que a mensagem seja igual ao valor SAIR. Espera-se primeiramente o inteiro representante da quantidade de bytes que sero enviados e efetua-se a leitura destes, que so convertidos em String para renderizao na sada padro. Com isto, temos nosso pequeno servidor de conexes Bluetooth que trabalha sobre um pequeno protocolo desenvolvido para leitura de mensagens enviadas. Podemos executar o nosso programa.

Execuo

5

Para executar o projeto, basta voc acessar o menu Run - Run. Algumas excees podem surgir se algum problema for encontrado. Abaixo esto descritos dois problemas principais de execuo. Native Library bluecove_x64 not available Isto significa que voc no possui as bibliotecas instaladas no Sistema Operacional para executar corretamente o Bluecove. No Ubuntu, basta voc instalar o pacote libbluetooth-dev para evitar este erro. Bluetooth Device is not available Esta mensagem diz que voc no possui um Bluetooth Radio instalado. Pode ser que o seu adaptador no est devidamente configurado. No meu caso, muitas vezes esqueo de conect-lo no computador. Devemos agora criar um aplicativo cliente que envie as mensagens conforme pequeno protocolo configurado no lao de repetio, utilizando um dispositivo Android. O prximo artigo ir explicar como criar este aplicativo que conecte no servio Bluetooth criado.

Consideraes FinaisO servidor criado muito simples, com certeza. Porm com ele podemos aprender a lgica bsica para envio de informaes e verificamos que a lgica muito semelhante a uma conexo TCP/IP. Podemos conferir a classe completa desenvolvida neste artigo logo abaixo. + expand source?package br.nom.camargo.wanderson.bluetooth.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnectionNotifier; /** * Servidor Bluetooth * @author Wanderson Henrique Camargo Rosa */ public class Server implements Runnable { /** * Fluxo de Execuo Principal */ public void run() { // Identificador nico de Conexo String uuid = "879c3537-ae66-4013-a677-9b7e5339d13c"; // Endereo para Conexo String address = "btspp://localhost:" + uuid.replace("-", ""); try { // Abertura de Conexo StreamConnectionNotifier notifier =

6

(StreamConnectionNotifier) Connector.open(address); // Fluxo de Conexo StreamConnection stream = notifier.acceptAndOpen(); // Captura de Fluxos InputStream input = stream.openInputStream(); OutputStream output = stream.openOutputStream(); // Lao de Repetio int size; byte content[]; // Auxiliares de Leitura String message = ""; // Mensagem Enviada pelo Cliente while (!message.equals("SAIR")) { // Tamanho dos Dados size = input.read(); // Quantidade de Bytes // Buffer de Leitura content = new byte[size]; // Preenchimento dos Dados input.read(content); // Entrada de Informao // Transformao da Mensagem Enviada message = new String(content); // Novo Elemento // Exibio na Sada Padro System.out.println(message); } } catch (IOException e) { // Erro Encontrado e.printStackTrace(); } } /** * Execuo Principal do Aplicativo * @param args Argumentos de Execuo */ public static void main(String args[]) { Server server = new Server(); server.run(); } }

Uma sequncia de caracteres que identificam um UUID possuem algumas regras de formao. Voc pode escolher qualquer valor para o seu aplicativo. Podemos utilizar aplicativos geradores de UUID disponveis online e de fcil utilizao. Procure saber mais informaes sobre o UUID. O Java no possui suporte a Bluetooth nativo. Isto significa que voc precisa utilizar bibliotecas externas para utilizao desta tecnologia em seus aplicativos. A Bluecove segue os padres estabalecidos pela especificao; podemos notar que a estrutura semelhante ao JavaME (microedition), desenvolvido para dispositivos mveis. Ela tambm usufrui de algumas DLLs e SOs para manipular Bluetooth, armazenadas dentro dos arquivos JAR. Engraado, no? Tambm verifique se a licena GPL do Bluecove compatvel com suas necessidades. O nosso prximo passo criar um aplicativo para Android que consiga enviar informaes para este servidor criado. Para isto, vamos inicializar uma visualizao para tornar o aplicativo mais interessante.

7

Conexo Bluetooth Android Parte 03: Visualizao ClienteEste o terceiro artigo sobre como criar uma conexo Bluetooth entre Android e computador. Anteriormente, desenvolvemos uma estrutura bsica de servidor que deve ser executado na mquina local. Agora vamos desenvolver a visualizao que ser utilizada pelo cliente para enviar mensagens ao servio criado.

IntroduoEste artigo ir demonstrar como construir a visualizao para o programa que envia mensagens para o servidor Bluetooth criado anteriormente, utilizando um dispositivo Android. No ser ensinado como deve ser instalado o ambiente de desenvolvimento ou Android SDK. Porm, vamos utilizar a API do Android 2.2 Froyo.

Criando o ProjetoVamos criar um Android Project de nome BluetoothClient no Eclipse. Estarei utilizando a API do Android 2.2 Froyo, mas j executei os mesmos testes sobre a 2.1 e possivelmente funcionar em outras verses anteriores. O nome do aplicativo receber o mesmo nome do projeto e vamos criar uma atividade inicial de nome ClientActivity. Por fim, confirme em Finish para criar o projeto.

Novo Projeto Cliente de Bluetooth O prximo passo ser a construo de uma estrutura inicial de desenvolvimento, criando a visualizao utilizada e capturando os elementos na atividade.

Estrutura Inicial

8

A atividade principal do aplicativo criado deve ser semelhante a prxima estrutura apresentada.package br.nom.camargo.wanderson.bluetooth.client; import android.app.Activity; import android.os.Bundle; /** * Cliente Bluetooth para Android * @author Wanderson Henrique Camargo Rosa */ public class ClientActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Cliente de Conexo Bluetooth } }

Buscando criar um ambiente interessante para demonstrar a transferncia de dados entre o Android e computador, vamos criar uma visualizao com uma caixa de texto que pode ser preenchida pelo usurio e um boto de envio da informao.

VisualizaoA atividade ClientActivity utiliza um recurso de layout j inicializado quando o projeto foi criado. Vamos modific-lo para preencher os requisitos descritos na Seo anterior. Vamos editar o arquivo res/layout/main.xml e adicionar uma caixa de texto do tipo EditText configurada com identificador igual a mensagem. Abaixo, vamos incluir um boto Button para envio das informaes com valor para identificador enviar. Podemos conferir o cdigo gerado pelo editor de visualizao e uma captura de tela do resultado. + expand source?

9

Visualizao dos Componentes Gerados Agora precisamos capturar os elementos da visualizao na atividade para que sejam desenvolvidos os mtodos responsveis pela conexo e envio das informaes ao servio.

Capturando os ComponentesNo mtodo onCreate da atividade principal ClientActivity do aplicativo, vamos incluir dois atributos que sero retirados da camada de visualizao. Inclua dois novos atributos de classe, descritos abaixo./** * Caixa de Mensagem */ private EditText mensagem; /** * Boto de Envio */ private Button enviar;

Agora vamos inicializ-los internamente ao mtodo de criao da atividade, solicitando camada de visualizao o ponteiro de acesso aos componentes.// Cliente de Conexo Bluetooth // Caixa de Texto mensagem = (EditText) findViewById(R.id.mensagem); // Boto de Envio enviar = (Button) findViewById(R.id.enviar);

Neste caso, ao pressionar o boto, a mensagem dever ser enviada para o servidor. Isto feito atravs do mtodo setOnClickListener do prprio boto, recebendo um objeto do tipo listener para executar a ao.

10

// Boto de Envio enviar = (Button) findViewById(R.id.enviar); enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Enviar a Mensagem } });

Criamos uma estrutura bsica visualizao, manipulada na classe de atividade e alguns componentes foram recuperados. O prximo artigo ir adicionar o recurso de conexo Bluetooth com o servidor e envio da mensagem escrita pelo usurio na caixa de texto.

Consideraes FinaisO desenvolvimento para Android possui uma funcionalidade muito interessante: a diviso da camada de visualizao e de controladoras. A criao de telas em XML torna a construo mais simples e genrica, podendo ser aplicvel a sistemas online, assim como o WebOS j trabalha, onde aplicativos podem ser desenvolvidos numa pgina em Javascript. Algumas pessoas podem achar diferente as capturas de tela deste artigo, com componentes de visualizao e barras de ferramentas modificadas. Isto acontece porque a ADT foi atualizada no ltimo ms, sofrendo algumas correes e melhorias. A atividade ClientController em seu estado atual pode ser conferida na ntegra logo abaixo, com todos os mtodos adicionados at o momento. + expand source?package br.nom.camargo.wanderson.bluetooth.client; import import import import import android.app.Activity; android.os.Bundle; android.view.View; android.widget.Button; android.widget.EditText;

/** * Cliente Bluetooth para Android * @author Wanderson Henrique Camargo Rosa */ public class ClientActivity extends Activity { /** * Caixa de Mensagem */ private EditText mensagem; /** * Boto de Envio */ private Button enviar; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

11

setContentView(R.layout.main); // Cliente de Conexo Bluetooth // Caixa de Texto mensagem = (EditText) findViewById(R.id.mensagem); // Boto de Envio enviar = (Button) findViewById(R.id.enviar); enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Enviar a Mensagem } }); } }

Agora que os componentes foram capturados na atividade, podemos manipular as informaes de entrada includas pelo usurio. Porm, ainda precisamos aprender como acessar a visualizao do aplicativo entre diferentes fluxos de processamento, para que as mensagens de alerta sejam exibidas corretamente ao usurio.

Conexo Bluetooth Android Parte 04: Mensagens de AlertaEste artigo pertence a srie sobre como criar uma conexo Bluetooth entre um computador e Android. Aps criar o servidor e a visualizao no cliente, vamos incluir um novo atributo de classe na atividade que possibilita a exibio de mensagens ao usurio em fluxos concorrentes de execuo, as famosas threads.

SincronizaoO Android possui um tratamento que evita o acesso de elementos de visualizao em diferentes fluxos de execuo, possivelmente para evitar o erro de sincronizao entre elementos. Devemos saber esta funcionalidade porque ser necessria a criao da conexo em uma thread, pois o acesso ao servidor bloqueante. Um mtodo bloqueante aquele que necessita acessar determinado recurso que nem sempre responde ao mesmo tempo em que a solicitao executada, trancando o fluxo de processamento. Nos prximos artigos vamos abrir uma conexo e enviar informaes atravs do Bluetooth para outro dispositivo que nem sempre responder rapidamente. Vamos adicionar dois novos recursos atividade. O objeto do tipo Handler o manipulador de mensagens confivel pelo Android, possibilitando a troca de informaes entre diferentes threads.

Manipulador

12

O manipulador ser criado como um atributo do tipo final e privado. O mtodo handleMessage sobrescrito durante a utilizao da classe annima, ser responsvel por exibir a mensagem corretamente no aplicativo./** * Manipulador de Mensagens */ private final Handler h = new Handler() { public void handleMessage(Message msg) { // Manipular Mensagem String content = (String) msg.obj; // Captura do Contedo da Mensagem Toast.makeText(ClientActivity.this, content, Toast.LENGTH_SHORT).show(); } };

O mtodo adicional receber o nome alert e por ele devem ser exibidas todos os alertas do aplicativo. Devemos informar ao manipulador uma mensagem de alerta, sendo esta acessada pelo mtodo handleMessage posteriormente. O mtodo tambm pertence estrutura da classe de atividade. Ao final, o mtodo de envio de mensagens do manipulador acessado, enviando o alerta para o usurio./** * Envia Mensagens entre Fluxos de Execuo * @param message Mensagem para Envio */ public void alert(String message) { Message m = h.obtainMessage(); m.obj = message; h.sendMessage(m); }

Lembrando sempre que estes blocos de cdigo devem ser acessados na estrutura da atividade. Eles sero responsveis pela exibio de mensagens ao usurio atravs da classe Toast. Os prximos artigos devero utilizar este mtodo para renderizar as mensagens de alerta informadas, criando uma estrutura inicial de execuo do aplicativo e como devemos conectar o Android no computador utilizando o programa servidor anteriormente finalizado.

Consideraes FinaisO Android possui uma segurana para acesso de visualizao entre diferentes threads. Caso voc necessite acessar um boto num outro fluxo diferente do principal, ser necessria a criao de um Handler para executar a tarefa. A estrutura da classe de atividade construda at ento pode ser conferida abaixo. + expand source?package br.nom.camargo.wanderson.bluetooth.client; import android.app.Activity; import android.os.Bundle;

13

import import import import import import

android.os.Handler; android.os.Message; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Toast;

/** * Cliente Bluetooth para Android * @author Wanderson Henrique Camargo Rosa */ public class ClientActivity extends Activity { /** * Caixa de Mensagem */ private EditText mensagem; /** * Boto de Envio */ private Button enviar; /** * Manipulador de Mensagens */ private final Handler h = new Handler() { public void handleMessage(Message msg) { // Manipular Mensagem String content = (String) msg.obj; // Captura do Contedo da Mensagem Toast.makeText(ClientActivity.this, content, Toast.LENGTH_SHORT).show(); } }; /** * Envia Mensagens entre Fluxos de Execuo * @param message Mensagem para Envio */ public void message(String message) { Message m = h.obtainMessage(); m.obj = message; h.sendMessage(m); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Cliente de Conexo Bluetooth // Caixa de Texto mensagem = (EditText) findViewById(R.id.mensagem); // Boto de Envio enviar = (Button) findViewById(R.id.enviar); enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Enviar a Mensagem } }); } }

14

O prximo artigo apresenta a primeira estrutura de envio de mensagens, abrindo a conexo com o servidor com classes especficas.

Conexo Bluetooth Android Parte 05: Abrindo ConexoOl! Esta semana pretendo terminar a srie sobre como criar uma conexo entre Android e computador, desenvolvendo um servidor Bluetooth utilizando Java e Bluecove e um aplicativo cliente para o smartphone. Aps criar uma visualizao que seja manipulvel e que possibilite o envio de mensagens para o nosso servidor programado, e um manipulador de mensagens de alerta, vamos abrir uma conexo.

Adicionando, no conheo emulador do Android que possua Bluetooth. Algum j deve ter desenvolvido um driver para acessar o adaptador da mquina local. Eu utilizo para programao meu Samsung Galaxy 5 I5500B modificado com Android 2.2 Froyo. Utilizando a mesma estrutura do projeto desenvolvido anteriormente, vamos adicionar novos recursos e criar uma conexo com o computador que est executando o servio Bluetooth. Primeiro voc precisa fazer algumas aes para que o computador reconhea o Android, pareando os dispositivos. Isto pode ser feito no menu de configuraes Bluetooth; peo desculpas mas no vou ensinar como parear dispositivos Bluetooth neste artigo, mas acho que o Orculo pode resolver. Aps sincronizar os dispositivos, vamos adicionar as permisses necessrias para manipulao do adaptador Bluetooth no Android.

Permisses BluetoothAbrindo o arquivo AndroidManifest.xml no Eclipse, um ambiente amigvel de edio deste XML disponibilizado. Abaixo, uma nova aba chamada Permissions est disponvel. Selecionando a opo Add, voc deve criar um novo elemento chamado Uses Permission. Uma nova caixa de seleo ir aparecer e basta selecionar a opo android.permission.BLUETOOTH. Salve o arquivo. Se acessarmos a aba AndroidManifest.xml, podemos analisar o cdigo fonte real do arquivo. Caso tudo esteja correto, voc ter uma linha que define a permisso da seguinte forma.

Lembre-se que esta permisso necessria porque vamos manipular o adaptador Bluetooth do dispositivo. Caso no esteja cadastrada, o aplicativo ir gerar um erro de permisso negada do sistema operacional.

Selecionando o Servidor15

Aps a seleo do boto que enviar as informaes adicionadas na caixa de texto pelo usurio, vamos solicitar ao Android o adaptador Bluetooth disponvel no mtodo onCreate. Se no existe um adaptador no dispositivo, o mtodo getDefaultAdapter ir retornar nulo, portanto devemos informar o usurio que no ser possvel executar a conexo porque no existe um adaptador. Lembre-se de utilizar o manipulador de mensagens de alerta criado anteriormente. Precisamos tambm verificar se o adaptador Bluetooth est habilitado.// Requisio do Adaptador BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { // No h Bluetooth // Mensagem de Erro ao Usurio alert("Adaptador no Encontrado"); finish(); } if (!adapter.isEnabled()) { // Bluetooth Habilitado? // Mensagem de Erro ao Usurio alert("Bluetooth Desabilitado"); finish(); }

Agora, vamos solicitar ao adaptador todos os dispositivos que esto pareados no sistema operacional. O mtodo de busca sequencial utilizado extremamente lento quando o nmero de dispositivos sincronizados n for relativamente grande. Porm, para a demonstrao neste artigo, isto no importa. No entanto, peo que execute uma busca mais aprimorada sobre a lista. Cada dispositivo possui um nome cadastrado e no nico. O mais interessante utilizar o MAC do adaptador Bluetooth instalado no servidor. Aqui, vou utilizar o nome de pareamento utilizado que o nome da minha mquina servidor. Note que voc deve alterar este nome para o que foi identificado pelo seu Android. Curiosidade. Para quem no sabe, Ganondorf um dos inimigos do Link e da Princesa Zelda. Toda a minha rede local ou dispositivos eletrnicos possuem nomes encontrados na srie. Meu celular Android chama-se Tingle, o HD Externo chama-se Ocarina, o servidor web recebeu o nome Dekutree, entre outros.// Dispositivos Pareados Set devices = adapter.getBondedDevices(); // Servidor Bluetooth BluetoothDevice server = null; String servername = "Ganondorf"; // Nome do Servidor // Pesquisa do Servidor Pareado for (BluetoothDevice device : devices) { // Lao de Busca if (servername.equals(device.getName())) { // Nomes Idnticos? server = device; // Dispositivo Encontrado e Selecionado } } // Dispositivo Encontrado? if (server == null) { // Mensagem de Erro ao Usurio alert("Servidor no Pareado"); finish(); }

16

Note que o ltimo bloco condicional do cdigo acima possui uma verificao, exibindo uma mensagem de erro caso o servidor no esteja na lista. Obviamente, voc pode modificar este tratamento.

Fluxo ConcorrenteComo a conexo Bluetooth bloqueante, necessitando esperar o outro dispositivo responder, precisamos colocar o nosso bloco de cdigo dentro de uma thread. O servidor Bluetooth encontrado no lao de repetio somente pode ser acessado na thread se a varivel esteja configurada como final. Vamos criar um novo elemento com o parmetro final e vamos cham-lo de computer.// Servidor Bluetooth final BluetoothDevice computer = server;

Agora podemos criar a estrutura que ser utilizada para conexo. Utilizando alguns recursos do Java, vamos criar um objeto do tipo Thread e sobrescrever o mtodo run. Feito isto, podemos executar o fluxo concorrente atravs do mtodo start.Thread connector = new Thread(){ public void run() { // Conexo Bluetooth } }; // Executando o Fluxo de Processamento connector.start(); // Inicializao

Inicializando a parte importante: desenvolver o mtodo interno de conexo. As prximas linhas estaro sendo adicionadas dentro do mtodo run.

Abrindo a ConexoInternamente ao mtodo run, vamos adicionar algumas linhas que sero importantes para a seleo dos fluxos de entrada e sada de dados, os famosos InputStream e OutputStream. Primeiramente vamos abrir um canal de conexo com o servidor utilizando o UUID configurado nos artigos passados. O UUID deve ser o mesmo do servidor, porm sem a retirada dos traos que dividem o valor do contedo. A partir da String, vamos criar um objeto utilizando o mtodo esttico UUID.fromString, atribuindo o resultado ao objeto ident. Aps, vamos criar um socket de conexo entre o Android e o computador utilizando o mtodo responsvel pela ao do objeto computer, informando o identificador da conexo. A partir deste ponto podemos ter uma exceo de entrada e sada de dados e precisamos incluir o cdigo dentro de um bloco try..catch.// Identificador nico do Servidor UUID ident = UUID.fromString("879c3537-ae66-4013-a677-9b7e5339d13c"); try { // Socket de Conexo BluetoothSocket s = // Conexo a Partir do Identificador nico

17

computer.createRfcommSocketToServiceRecord(ident); } catch (IOException e) { // Erro de Entrada e Sada de Dados // Mensagem de Erro ao Usurio alert("Erro de Conexo"); finish(); }

Lembre-se de que o cdigo acima est dentro do mtodo run e que o UUID da conexo deve ser o mesmo utilizado pelo servidor. Voc foi encorajado a utilizar outro valor no servidor, no esquea disto. Abaixo da criao do socket, vamos solicitar a sua conexo com o servidor, executando o mtodo connect. O cdigo abaixo muito semelhante a uma conexo TCP/IP no Java. Aps, simplesmente capture os fluxos de entrada e sada de dados do socket, armazenando os resultados nos objetos especficos.// Conectar ao Servidor s.connect(); // Execuo Bloqueante // Fluxos de Entrada e Sada de Dados InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream();

Feito isto, vamos adicionar trs novos parmetros atividade ClientActivity, visando armazenar o socket da conexo e os fluxos de entrada e sada de dados, que devero ser utilizados para enviar e receber mensagens do servidor. Estes parmetros so externos ao mtodo run, fazendo parte da estrutura de classe na atividade do aplicativo./** * Socket de Conexo */ private BluetoothSocket socket; /** * Fluxo de Entrada de Dados */ private InputStream input; /** * Fluxo de Sada de Dados */ private OutputStream output;

Por fim, vamos armazenar os elementos encontrados aps a conexo nos atributos da classe criados acima, possibilitando que outros pontos da atividade utilizem os objetos criados. Tambm vamos informar o usurio de que a conexo foi aberta com sucesso. O bloco abaixo est logo aps a abertura dos fluxos de conexo do mtodo run.// Captura de Objetos socket = s; // Socket de Conexo input = in; // Fluxo de Entrada de Dados output = out; // Fluxo de Sada de Dados // Informar sobre Conexo alert("Conexo Aberta");

18

Feito. Acabamos de abrir uma conexo Bluetooth com o servidor criado nos artigos iniciais desta sequncia. Estamos prontos para enviar mensagens utilizando os componentes de visualizao adicionados ao aplicativo. Visando dividir as tarefas, isto ser desenvolvido nos prximos artigos.

Consideraes FinaisA abertura de conexes Blueooth muito semelhante a estrutura TCP/IP no Java. Isto possvel pela abstrao de execuo includa, deixando a cargo da linguagem e das classes implementadas as tarefas de baixo nvel. Adicionalmente, vamos sobrescrever o mtodo onDestroy da atividade e fechar o socket de conexo, bem como os fluxos de entrada e sada. No esquea de executar o mtodo sobrescrito.public void onDestroy() { super.onDestroy(); // Mtodo Sobrescrito if (socket != null) { // Socket Configurado? try { socket.close(); // Fecha Conexo } catch (IOException e) { // Erro Encontrado? // Mensagem de Erro ao Usurio alert("Erro ao Fechar Socket"); } } }

Lembre-se de sempre utilizar o mesmo UUID entre o cliente e servidor, deixando os traos para que o Android aceite como um valor vlido, diferentemente da classe servidor do Bluecove. Podemos conferir a classe completa criada at o momento no cdigo abaixo. + expand source?package br.nom.camargo.wanderson.bluetooth.client; import import import import import import import import import import import import import import import import java.io.IOException; java.io.InputStream; java.io.OutputStream; java.util.Set; java.util.UUID; android.app.Activity; android.bluetooth.BluetoothAdapter; android.bluetooth.BluetoothDevice; android.bluetooth.BluetoothSocket; android.os.Bundle; android.os.Handler; android.os.Message; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Toast;

/** * Cliente Bluetooth para Android

19

* @author Wanderson Henrique Camargo Rosa */ public class ClientActivity extends Activity { /** * Caixa de Mensagem */ private EditText mensagem; /** * Boto de Envio */ private Button enviar; /** * Socket de Conexo */ private BluetoothSocket socket; /** * Fluxo de Entrada de Dados */ private InputStream input; /** * Fluxo de Sada de Dados */ private OutputStream output; /** * Manipulador de Mensagens */ private final Handler h = new Handler() { public void handleMessage(Message msg) { // Manipular Mensagem String content = (String) msg.obj; // Captura do Contedo da Mensagem Toast.makeText(ClientActivity.this, content, Toast.LENGTH_SHORT).show(); } }; /** * Envia Mensagens entre Fluxos de Execuo * @param message Mensagem para Envio */ public void alert(String message) { Message m = h.obtainMessage(); m.obj = message; h.sendMessage(m); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Cliente de Conexo Bluetooth // Caixa de Texto mensagem = (EditText) findViewById(R.id.mensagem); // Boto de Envio enviar = (Button) findViewById(R.id.enviar);

20

enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Enviar a Mensagem } }); // Requisio do Adaptador BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { // No h Bluetooth // Mensagem de Erro ao Usurio alert("Adaptador no Encontrado"); finish(); } if (!adapter.isEnabled()) { // Bluetooth Habilitado? // Mensagem de Erro ao Usurio alert("Bluetooth Desabilitado"); finish(); } // Dispositivos Pareados Set devices = adapter.getBondedDevices(); // Servidor Bluetooth BluetoothDevice server = null; String servername = "Ganondorf"; // Nome do Servidor // Pesquisa do Servidor Pareado for (BluetoothDevice device : devices) { // Lao de Busca if (servername.equals(device.getName())) { // Nomes Idnticos? server = device; // Dispositivo Encontrado e Selecionado } } // Dispositivo Encontrado? if (server == null) { // Mensagem de Erro ao Usurio alert("Servidor no Pareado"); finish(); } // Servidor Bluetooth final BluetoothDevice computer = server; // Abrindo a Conexo Thread connector = new Thread(){ public void run() { // Identificador nico do Servidor UUID ident = UUID.fromString("879c3537-ae66-4013-a6779b7e5339d13c"); try { // Socket de Conexo BluetoothSocket s = // Conexo a Partir do Identificador nico computer.createRfcommSocketToServiceRecord(ide nt); // Conectar ao Servidor s.connect(); // Execuo Bloqueante // Fluxos de Entrada e Sada de Dados InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); // Captura de Objetos socket = s; // Socket de Conexo input = in; // Fluxo de Entrada de Dados output = out; // Fluxo de Sada de Dados // Informar sobre Conexo

21

alert("Conexo Aberta"); } catch (IOException e) { // Erro de Entrada e Sada de Dados // Mensagem de Erro ao Usurio alert("Erro de Conexo"); finish(); } } }; // Executando o Fluxo de Processamento connector.start(); // Inicializao } public void onDestroy() { super.onDestroy(); // Mtodo Sobrescrito if (socket != null) { // Socket Configurado? try { socket.close(); // Fecha Conexo } catch (IOException e) { // Erro Encontrado? // Mensagem de Erro ao Usurio alert("Erro ao Fechar Socket"); } } } }

Existem muitas outras coisas que podem ser executadas neste aplicativo. Podemos, por exemplo, solicitar que o sistema operacional habilite o adaptador Bluetooth caso ele esteja desligado. Adicionar um objeto que exiba uma animao, informando que o dispositivo est tentando conectar ao servidor tambm importante. Desde o incio, posso me considerar um apaixonado pelo sistema operacional Android. Usufruir de um kernel de Linux num aparelho celular acreditar no sonho do Torvalds. Ter a possibilidade de tornar o celular um tijolo atravs do comando rm -rf / --nopreserve-root muito empolgante e desafiador. Nosso prximo passo enviar uma mensagem includa na caixa de texto da visualizao para o servidor conectado, finalizando assim a sequncia de conexo Bluetooth.

Conexo Bluetooth Android Parte 06 Final: Enviando InformaesWanderson August 06, 2011 Android 3 Comments Tags: bluetooth, eclipse, java, tutorial Este artigo pertence sequncia sobre como criar uma conexo entre computador e Android, desenvolvendo um servidor Bluetooth na mquina local e um aplicativo cliente para o celular. Utilizando uma visualizao simples e aps abrir a conexo no cliente com o servidor, vamos desenvolver o mtodo que envia o texto adicionado pelo

22

usurio para o servidor e finalizar o desenvolvimento.

Vamos adicionar um novo recurso ao boto de envio da atividade ClientActivity adicionada anteriormente. A regra muito simples: quando o usurio selecionar o envio das informaes, vamos verificar se existe algum texto para ser transferido ao servidor utilizando a conexo Bluetooth j inicializada.

Estrutura InicialO objeto enviar interno ao mtodo onCreate da atividade, pertence visualizao e representado pelo boto de envio da mensagem. Vamos continuar o desenvolvimento do listener inicializado anteriormente, adicionando o novo recurso de transferncia. O envio do texto tambm bloqueante, assim como o incio da conexo. Para evitar que o celular congele, devemos enviar o texto numa nova thread. Primeiramente, vamos capturar o texto informado pelo usurio na caixa especfica. O contedo necessita receber o modificador final para que o objeto do tipo Thread acesse-o para envio.// Boto de Envio enviar = (Button) findViewById(R.id.enviar); enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Captura do Texto final String conteudo = mensagem.getText().toString(); // Transferidor de Dados Thread sender = new Thread(){ public void run() { // Enviar o Contedo } }; // Executando o Fluxo de Processamento sender.start(); // Inicializao } });

Verifique tambm que foi criada uma nova thread para enviar as informaes e que esta foi executado em modo concorrente atravs do mtodo start. Agora podemos enviar informaes para o servidor.

Enviando InformaesDentro do mtodo run do listener do boto, vamos adicionar a transferncia de informaes entre o cliente e o servidor Bluetooth. Anteriormente, foi discutido um pequeno protocolo para envio de informaes, onde primeiramente devemos enviar a quantidade de bytes que sero transferidos e, aps, os bytes propriamente ditos. Capturando o fluxo de sada de dados OutputStream registrado durante a abertura de conexo, devemos informar a quantidade de bytes que sero transferidos. O contedo capturado da caixa de texto ser transformado em bytes puros e todo o protocolo ser respeitado. Quando o fluxo de sada acessado, um erro de entrada ou sada de dados poder ser encontrado; um pequeno tratamento foi includo, alertando o usurio sobre problema encontrado.23

public void run() { // Contedo para Envio byte content[] = conteudo.getBytes(); try { // Possibilidade de Erro output.write(content.length); // Tamanho do Contedo output.write(content); // Contedo Propriamente Dito // Aviso de Sucesso ao Usurio alert("Texto Enviado"); } catch (IOException e) { // Erro Encontrado // Aviso de Erro ao Usurio alert("Erro na Transferncia"); } }

Se tudo ocorreu conforme previsto, se a conexo foi executada com sucesso e a transferncia foi finalizada, voc pode conferir o texto na sada padro do servidor. Caso a mensagem for igual a SAIR, o servidor ser fechado.

ResultadosConferindo os resultados do desenvolvimento, o aplicativo gerado foi executado sobre o celular Samsung Galaxy 5 I5500B com Android Froyo 2.2, conectando-se ao servidor em execuo. Devemos ter a certeza de que o computador local e o celular esto pareados, acessando as configuraes do Bluetooth no Android.

Confirmao de Pareamento Aps, vamos executar o servidor Bluetooth desenvolvido anteriormente. Para iniciar o servio, vamos utilizar o prprio Run do Eclipse da mesma forma que o artigo anterior onde o desenvolvemos. Precisamos inicializar o aplicativo no Android. Primeiro devemos habilitar o Bluetooth j que nosso aplicativo no executa isto automaticamente. Aps, vamos abrir o aplicativo utilizando o prprio Eclipse. Uma mensagem deve ser exibida se a conexo foi bem sucedida.24

Conexo Bluetooth Aberta Podemos digitar qualquer texto e este ser enviado para o servidor, que exibir na sada padro o texto enviado. Finalmente conseguimos criar uma conexo e enviar os dados ao servidor com sucesso. Podemos conferir a classe de atividade completa logo abaixo. + expand source?package br.nom.camargo.wanderson.bluetooth.client; import import import import import import import import import import import import import import import import java.io.IOException; java.io.InputStream; java.io.OutputStream; java.util.Set; java.util.UUID; android.app.Activity; android.bluetooth.BluetoothAdapter; android.bluetooth.BluetoothDevice; android.bluetooth.BluetoothSocket; android.os.Bundle; android.os.Handler; android.os.Message; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Toast;

/** * Cliente Bluetooth para Android * @author Wanderson Henrique Camargo Rosa */ public class ClientActivity extends Activity { /** * Caixa de Mensagem */ private EditText mensagem;

25

/** * Boto de Envio */ private Button enviar; /** * Socket de Conexo */ private BluetoothSocket socket; /** * Fluxo de Entrada de Dados */ private InputStream input; /** * Fluxo de Sada de Dados */ private OutputStream output; /** * Manipulador de Mensagens */ private final Handler h = new Handler() { public void handleMessage(Message msg) { // Manipular Mensagem String content = (String) msg.obj; // Captura do Contedo da Mensagem Toast.makeText(ClientActivity.this, content, Toast.LENGTH_SHORT).show(); } }; /** * Envia Mensagens entre Fluxos de Execuo * @param message Mensagem para Envio */ public void alert(String message) { Message m = h.obtainMessage(); m.obj = message; h.sendMessage(m); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Cliente de Conexo Bluetooth // Caixa de Texto mensagem = (EditText) findViewById(R.id.mensagem); // Boto de Envio enviar = (Button) findViewById(R.id.enviar); enviar.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Captura do Texto final String conteudo = mensagem.getText().toString(); // Transferidor de Dados Thread sender = new Thread(){ public void run() { // Contedo para Envio byte content[] = conteudo.getBytes();

26

try { // Possibilidade de Erro output.write(content.length); // Tamanho do Contedo output.write(content); // Contedo Propriamente Dito // Aviso de Sucesso ao Usurio alert("Texto Enviado"); } catch (IOException e) { // Erro Encontrado // Aviso de Erro ao Usurio alert("Erro na Transferncia"); } } }; // Executando o Fluxo de Processamento sender.start(); // Inicializao } }); // Requisio do Adaptador BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { // No h Bluetooth // Mensagem de Erro ao Usurio alert("Adaptador no Encontrado"); finish(); } if (!adapter.isEnabled()) { // Bluetooth Habilitado? // Mensagem de Erro ao Usurio alert("Bluetooth Desabilitado"); finish(); } // Dispositivos Pareados Set devices = adapter.getBondedDevices(); // Servidor Bluetooth BluetoothDevice server = null; String servername = "Ganondorf"; // Nome do Servidor // Pesquisa do Servidor Pareado for (BluetoothDevice device : devices) { // Lao de Busca if (servername.equals(device.getName())) { // Nomes Idnticos? server = device; // Dispositivo Encontrado e Selecionado } } // Dispositivo Encontrado? if (server == null) { // Mensagem de Erro ao Usurio alert("Servidor no Pareado"); finish(); } // Servidor Bluetooth final BluetoothDevice computer = server; // Abrindo a Conexo Thread connector = new Thread(){ public void run() { // Identificador nico do Servidor UUID ident = UUID.fromString("879c3537-ae66-4013-a6779b7e5339d13c"); try { // Socket de Conexo BluetoothSocket s = // Conexo a Partir do Identificador nico

27

computer.createRfcommSocketToServiceRecord(ide nt); // Conectar ao Servidor s.connect(); // Execuo Bloqueante // Fluxos de Entrada e Sada de Dados InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); // Captura de Objetos socket = s; // Socket de Conexo input = in; // Fluxo de Entrada de Dados output = out; // Fluxo de Sada de Dados // Informar sobre Conexo alert("Conexo Aberta"); } catch (IOException e) { // Erro de Entrada e Sada de Dados // Mensagem de Erro ao Usurio alert("Erro de Conexo"); finish(); } } }; // Executando o Fluxo de Processamento connector.start(); // Inicializao } public void onDestroy() { super.onDestroy(); // Mtodo Sobrescrito if (socket != null) { // Socket Configurado? try { socket.close(); // Fecha Conexo } catch (IOException e) { // Erro Encontrado? // Mensagem de Erro ao Usurio alert("Erro ao Fechar Socket"); } } } }

Consideraes FinaisFinalizando esta sequncia sobre como criar uma conexo Bluetooth entre Android e um servidor criado em Java na mquina local, sinto-me orgulhoso de colocar todas estas informaes aqui no Blog. O cdigo fonte est disponvel na Seo de Anexos deste artigo. Estes documentos no existiriam sem a solicitao do @will_battisti, colega em Programao para Dispositivos Mveis em 2011/1 na Unisinos. Muito obrigado, Will! Tambm agradeo ao Guilherme Costa por estar sempre presente e perguntando quando toda a sequncia estaria disponvel. Peo desculpas pela demora e pacincia, Guilherme! J ao Rafael Brunello fico muito feliz pelos comentrios durante a sequncia, isto sempre ajuda no desenvolvimento; muito obrigado, Rafael! Ao final, agradeo a todas as pessoas que, de alguma forma, contribuiram para a criao destes artigos sobre conexo Bluetooth. Todos os leitores so bem vindos e espero que estes comentem suas dvidas, sempre bem vindas.28

O que voc ir criar utilizando este cdigo? Eu desenvolvi um aplicativo para movimentao de slides em apresentaes utilizando meu Android. O limite da imaginao infinito. Uma tima dica trabalhar com o acelermetro, trabalhando em algum ambiente renderizado na mquina local que seja manipulvel pelo Android apenas com movimentos. Isto seria o meu segundo trabalho da disciplina, que praticamente no saiu do papel.

Fonte de pesquisa: http://www.wanderson.camargo.nom.br/2011/08/conexao-bluetoothandroid-parte-06-final-enviando-informacoes/

29