蓝牙是一种支持设备短距离传输数据的无线技术。android在2.0以后提供了这方面的支持。 
从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 
1.设置权限 
在manifest中配置

  1. <uses-permission android:name="android.permission.BLUETOOTH"/>
  2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

2.启动蓝牙 
首先要查看本机是否支持蓝牙,获取BluetoothAdapter蓝牙适配器对象

  1. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  2. if(mBluetoothAdapter == null){
  3. //表明此手机不支持蓝牙
  4. return;
  5. }
  6. if(!mBluetoothAdapter.isEnabled()){ //蓝牙未开启,则开启蓝牙
  7. Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  8. startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
  9. }
  10. //......
  11. public void onActivityResult(int requestCode, int resultCode, Intent data){
  12. if(requestCode == REQUEST_ENABLE_BT){
  13. if(requestCode == RESULT_OK){
  14. //蓝牙已经开启
  15. }
  16. }
  17. }

3。发现蓝牙设备 
这里可以细分为几个方面 
(1)使本机蓝牙处于可见(即处于易被搜索到状态),便于其他设备发现本机蓝牙

  1. //使本机蓝牙在300秒内可被搜索
  2. private void ensureDiscoverable() {
  3. if (mBluetoothAdapter.getScanMode() !=
  4. BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
  5. Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  6. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  7. startActivity(discoverableIntent);
  8. }
  9. }

(2)查找已经配对的蓝牙设备,即以前已经配对过的设备

  1. Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
  2. if (pairedDevices.size() > 0) {
  3. findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
  4. for (BluetoothDevice device : pairedDevices) {
  5. //device.getName() +" "+ device.getAddress());
  6. }
  7. } else {
  8. mPairedDevicesArrayAdapter.add("没有找到已匹对的设备");
  9. }

(3)通过mBluetoothAdapter.startDiscovery();搜索设备,要获得此搜索的结果需要注册 
一个BroadcastReceiver来获取。先注册再获取信息,然后处理

  1. //注册,当一个设备被发现时调用onReceive
  2. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  3. this.registerReceiver(mReceiver, filter);
  4. //当搜索结束后调用onReceive
  5. filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  6. this.registerReceiver(mReceiver, filter);
  7. //.......
  8. private BroadcastReceiver mReceiver = new BroadcastReceiver() {
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. String action = intent.getAction();
  12. if(BluetoothDevice.ACTION_FOUND.equals(action)){
  13. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  14. // 已经配对的则跳过
  15. if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
  16. mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  //保存设备地址与名字
  17. }
  18. }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  //搜索结束
  19. if (mNewDevicesArrayAdapter.getCount() == 0) {
  20. mNewDevicesArrayAdapter.add("没有搜索到设备");
  21. }
  22. }
  23. }
  24. };

4.建立连接 
查找到设备 后,则需要建立本机与其他设备之间的连接。 
一般用本机搜索其他蓝牙设备时,本机可以作为一个服务端,接收其他设备的连接。 
启动一个服务器端的线程,死循环等待客户端的连接,这与ServerSocket极为相似。 
这个线程在准备连接之前启动

  1. //UUID可以看做一个端口号
  2. private static final UUID MY_UUID =
  3. UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
  4. //像一个服务器一样时刻监听是否有连接建立
  5. private class AcceptThread extends Thread{
  6. private BluetoothServerSocket serverSocket;
  7. public AcceptThread(boolean secure){
  8. BluetoothServerSocket temp = null;
  9. try {
  10. temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
  11. NAME_INSECURE, MY_UUID);
  12. } catch (IOException e) {
  13. Log.e("app", "listen() failed", e);
  14. }
  15. serverSocket = temp;
  16. }
  17. public void run(){
  18. BluetoothSocket socket=null;
  19. while(true){
  20. try {
  21. socket = serverSocket.accept();
  22. } catch (IOException e) {
  23. Log.e("app", "accept() failed", e);
  24. break;
  25. }
  26. }
  27. if(socket!=null){
  28. //此时可以新建一个数据交换线程,把此socket传进去
  29. }
  30. }
  31. //取消监听
  32. public void cancel(){
  33. try {
  34. serverSocket.close();
  35. } catch (IOException e) {
  36. Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
  37. }
  38. }
  39. }

搜索到设备后可以获取设备的地址,通过此地址获取一个BluetoothDeviced对象,可以看做客户端,通过此对象device.createRfcommSocketToServiceRecord(MY_UUID);同一个UUID可与服务器建立连接获取另一个socket对象,由此服务端与客户端各有一个socket对象,此时 
他们可以互相交换数据了。 
创立客户端socket可建立线程

  1. //另一个设备去连接本机,相当于客户端
  2. private class ConnectThread extends Thread{
  3. private BluetoothSocket socket;
  4. private BluetoothDevice device;
  5. public ConnectThread(BluetoothDevice device,boolean secure){
  6. this.device = device;
  7. BluetoothSocket tmp = null;
  8. try {
  9. tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
  10. } catch (IOException e) {
  11. Log.e("app", "create() failed", e);
  12. }
  13. }
  14. public void run(){
  15. mBluetoothAdapter.cancelDiscovery();    //取消设备查找
  16. try {
  17. socket.connect();
  18. } catch (IOException e) {
  19. try {
  20. socket.close();
  21. } catch (IOException e1) {
  22. Log.e("app", "unable to close() "+
  23. " socket during connection failure", e1);
  24. }
  25. connetionFailed();  //连接失败
  26. return;
  27. }
  28. //此时可以新建一个数据交换线程,把此socket传进去
  29. }
  30. public void cancel() {
  31. try {
  32. socket.close();
  33. } catch (IOException e) {
  34. Log.e("app", "close() of connect  socket failed", e);
  35. }
  36. }
  37. }

5.建立数据通信线程,进行读取数据

  1. //建立连接后,进行数据通信的线程
  2. private class ConnectedThread extends Thread{
  3. private BluetoothSocket socket;
  4. private InputStream inStream;
  5. private OutputStream outStream;
  6. public ConnectedThread(BluetoothSocket socket){
  7. this.socket = socket;
  8. try {
  9. //获得输入输出流
  10. inStream = socket.getInputStream();
  11. outStream = socket.getOutputStream();
  12. } catch (IOException e) {
  13. Log.e("app", "temp sockets not created", e);
  14. }
  15. }
  16. public void run(){
  17. byte[] buff = new byte[1024];
  18. int len=0;
  19. //读数据需不断监听,写不需要
  20. while(true){
  21. try {
  22. len = inStream.read(buff);
  23. //把读取到的数据发送给UI进行显示
  24. Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,
  25. len, -1, buff);
  26. msg.sendToTarget();
  27. } catch (IOException e) {
  28. Log.e("app", "disconnected", e);
  29. connectionLost();   //失去连接
  30. start();    //重新启动服务器
  31. break;
  32. }
  33. }
  34. }
  35. public void write(byte[] buffer) {
  36. try {
  37. outStream.write(buffer);
  38. // Share the sent message back to the UI Activity
  39. handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
  40. .sendToTarget();
  41. } catch (IOException e) {
  42. Log.e("app", "Exception during write", e);
  43. }
  44. }
  45. public void cancel() {
  46. try {
  47. socket.close();
  48. } catch (IOException e) {
  49. Log.e("app", "close() of connect socket failed", e);
  50. }
  51. }
  52. }

到这里,蓝牙通信的基本操作已经全部完成。

Android蓝牙操作笔记(转)的更多相关文章

  1. Android蓝牙操作笔记

    蓝牙是一种支持设备短距离传输数据的无线技术.android在2.0以后提供了这方面的支持. 从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 1.设置权限 在manifest中配置 ...

  2. Android蓝牙学习笔记

    一 Bluetooth基本概念 蓝牙是无线数据和语音传输的开放式标准,它将各种通信设备.计算机及其终端设备.各种数字数据系统.甚至家用电器采用无线方式联接起来.它的传输距离为10cm-10m,如果增加 ...

  3. Android 蓝牙操作详解

    1.启用蓝牙并使设备处于可发现状态    1.1 在使用BluetoothAdapter类的实例进操作之前,应启用isEnable()方法检查设备是否启用了蓝牙适配器.       // 使用意图提示 ...

  4. Android蓝牙操作

    1.添加蓝牙权限 <uses-permission android:name = "android.permission.BLUETOOTH"/> <!--启用应 ...

  5. Android:日常学习笔记(10)———使用LitePal操作数据库

    Android:日常学习笔记(10)———使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式 ...

  6. Android群英传笔记——第一章:Android体系与系统架构

    Android群英传笔记--第一章:Android体系与系统架构 图片都是摘抄自网络 今天确实挺忙的,不过把第一章的笔记做一下还是可以的,嘿嘿 1.1 Google的生态圈 还是得从Android的起 ...

  7. Android自动化学习笔记:编写MonkeyRunner脚本的几种方式

    ---------------------------------------------------------------------------------------------------- ...

  8. Android自动化学习笔记之MonkeyRunner:官方介绍和简单实例

    ---------------------------------------------------------------------------------------------------- ...

  9. android蓝牙打印机

    您还未登录!|登录|注册|帮助 首页 业界 移动 云计算 研发 论坛 博客 下载 更多 reality_jie的专栏 编程的过程是一种微妙的享受       目录视图 摘要视图 订阅 CSDN2013 ...

随机推荐

  1. [转载]windows下安装Python虚拟环境virtualenvwrapper-win

    1 前言 由于Python的版本众多,还有Python2和Python3的争论,因此有些软件包或第三方库就容易出现版本不兼容的问题. 通过 virtualenv 这个工具,就可以构建一系列 虚拟的Py ...

  2. 利用Xilinx中的ROM构造查找表来计算sin和cos的方法探讨

    1.使用matlab制作.coe文件 查找表的构造 构造256点的正余弦表 exp(-j*2*pi*(0:255)/256),分别得到 cos和sin的查找表 matlab代码: 求sin fid = ...

  3. hadoop 生态系统版本对应问题

    http://hbase.apache.org/book.html 这是hortonworks的哦哦哦哦哦哦哦哦哦哦哦哦 Hadoop 2.x is better than Hadoop 1.x Ha ...

  4. Help Me with the Game

    Help Me with the GameCrawling in process... Crawling failed Description Your task is to read a pictu ...

  5. struts2.0 struts.xml配置文件详解

    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN&quo ...

  6. 疯狂java讲义笔记 2.3.7

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...

  7. Oracle预估的基数算法

    SQL> create table t as select * from dba_objects; Table created. SQL> create index idx_t on t( ...

  8. C参数计算

    C‘计算参数时,从右向左压栈的 int a[]={1,3,4}; int * ptr=a; pirntf("%d,%d\n",*ptr,*(++ptr)); 输出都是3:

  9. 「Poetize7」Freda的访客

    描述 Description 小猫们看到蛋糕比饼干大之后,普遍认为蛋糕比饼干要好>.<.所以,如果Freda 给了第i 只小猫蛋糕且这个小猫是第一个吃到蛋糕的,那么就必须给第i+2,i+4 ...

  10. 3A. Shortest path of the king

    给你一个的棋盘, 问:从一个坐标到达另一个坐标需要多少步? 每次移动可以是八个方向.   #include <iostream> #include <cmath> #inclu ...