Android 读取蓝牙设备信息开发

(1)Android手机一般以客户端的角色主动连接SPP协议设备(接上蓝牙模块的数字传感器),连接流程是:
  1.使用registerReceiver注册BroadcastReceiver来获取蓝牙状态、搜索设备等消息;
  2.使用BlueAdatper的搜索;
  3.在BroadcastReceiver的onReceive()里取得搜索所得的蓝牙设备信息(如名称,MAC,RSSI);
  4.通过设备的MAC地址来建立一个BluetoothDevice对象;

  5.由BluetoothDevice衍生出BluetoothSocket,准备SOCKET来读写设备;

  6.通过BluetoothSocket的createRfcommSocketToServiceRecord()方法来选择连接的协议/服务,这里用的是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB);
  7.Connect之后(如果还没配对则系统自动提示),使用BluetoothSocket的getInputStream()和getOutputStream()来读写蓝牙设备。

****************注意:对于UUID,必须使用Android的SSP(协议栈默认)的UUID:00001101-0000-1000-8000-00805F9B34FB才能正常和外部的,也是SSP串口的蓝牙设备去连接。

(2)添加权限:

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

(3)BluetoothAdapter类:

BluetoothAdapter类简单点来说就是代表了本设备(手机、电脑等)的蓝牙适配器对象,通过它我们可以蓝牙设备进行基本开发了。

主要有如下功能:

  1、开关蓝牙设备

  2、扫描蓝牙设备

  3、设置/获取蓝牙状态信息,例如:蓝牙状态值、蓝牙Name、蓝牙Mac地址等;

BluetoothAdapter初始化并提示打开蓝牙使用:

 1 private BluetoothAdapter  mBluetoothAdapter;
 2 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 3 if (!mBluetoothAdapter.isEnabled()) {
 4     //弹出对话框提示用户是后打开
 5     Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
 6     startActivity(intent);
 7     //  startActivityForResult(intent, REQUEST_ENABLE);
 8     //不做提示,强行打开
 9     // mBluetoothAdapter.enable();
10 }

创建监听蓝牙状态的广播:

 1 BroadcastReceiver mFoundReceiver = new BroadcastReceiver() {
 2
 3         public void onReceive(Context context, Intent intent) {
 4             String action = intent.getAction();
 5             //找到设备
 6             if (BluetoothDevice.ACTION_FOUND.equals(action)) {
 7                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 8                 // 添加进一个设备列表,进行显示。
12                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
13                     Log.v(TAG, "find device:" + device.getName() + device.getAddress());
14                 }
15             }
16             //搜索完成
17             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
18                 cancelDiscovery();20             }
21         }
22     };

注册广播监听蓝牙状态:

 1 private void startDiscovery() { 5     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);//开启搜索
 6     registerReceiver(mFoundReceiver, filter);
 7     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成
 8     registerReceiver(mFoundReceiver, filter);15     mBluetoothAdapter.startDiscovery();17 }

开启和关闭蓝牙扫描:

// 开启
mBluetoothAdapter.startDiscovery();
// 关闭
mBluetoothAdapter.cancelDiscovery();

点击扫描到的列表,传递点击项的BluetoothDevice通过putExtra给蓝牙数据显示界面。

4)进行BluetoothSocket socket 和 BluetoothDevice mBluetoothDevice 进行操作。

 1 private class ConnectThread extends Thread {
 2
 3         public ConnectThread(BluetoothDevice device) {
 4             try {
 5                 socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
 6             } catch (IOException e) {
 7                 e.printStackTrace();
 8             }
10         }
11
12         public void run() {
13             while (mAutoConnectInterruptTime < 5) {
14                 try {
15
16                     socket.connect();
17                     runOnUiThread(new Runnable() {
18                         @Override
19                         public void run() {
20                             // TODO 显示连接成功
21                         }
22                     });
23                     isConnect = true;
24                     mAutoConnectInterruptTime = 0;
25                     manageConnectedSocket(socket); // 创建新的线程对蓝牙进行数据读取。
26                     break;
27
28                 } catch (Exception e) {
29                     e.printStackTrace();
30                     mAutoConnectInterruptTime++;
31
32                     try {
33                         Thread.sleep(2000);
34                     } catch (InterruptedException e1) {
35                         e1.printStackTrace();
36                     }
37
38                     runOnUiThread(new Runnable() {
39                         @Override
40                         public void run() {
41                             // TODO 显示连接失败
42                         }
43                     });
44                     // TODO 进行对 inputStream outputStream socket 进行关闭 置空.
45                     return;
46                 }
47             }
48
49         }
50
51         public void cancel() {
52             try {
53                 socket.close();
54             } catch (IOException e) {
55                 e.printStackTrace();
56             }
57         }
58     }

(5)通过BluetoothSocket socket 蓝牙数据读取:

 1 public class Receive extends Thread {
 2         // 变量 略过
 3
 4         // 构造方法
 5         public Receive(BluetoothSocket socket) {
 6
 7             // 获取输入流
 8             try {
 9                 inputStream = socket.getInputStream();
10                 outputStream = socket.getOutputStream();
11             } catch (IOException e) {
12                 e.printStackTrace();
13             }
14         }
15
16         @Override
17         public void run() {
18             final byte[] bytes = new byte[1024];// 缓冲数据流
19             int          count;// 返回读取到的数据
20             // 监听输入流
21             try {
22                 while (inputStream != null && (count = inputStream.read(bytes)) != -1) {
23                     //获取有效部分
24                     final byte[] contents = new byte[count];
25                     for (int i = 0; i < contents.length; i++) {
26                         contents[i] = bytes[i];
27                     }
28                     parse(contents); // TODO 对读取到数据进行转换
29                 }
30             } catch (Exception e) {
31                 e.printStackTrace();
32             }
33
34             ConnectThread connectBtThread = new ConnectThread(mBluetoothDevice);
35             connectBtThread.start();
36             // TODO 进行对 inputStream outputStream socket 进行关闭 置空。
37             runOnUiThread(new Runnable() {
38                 @Override
39                 public void run() {
40                     // TODO 关闭蓝牙连接
41                 }
42             });
43             // TODO inputStream outputStream socket 进行关闭 置空
44         }
45     }

参考:

关于用到BluetoothServerSocket和BluetoothSocket两个类来建立Server端和Client端,还需要使用到一些关于流(Stream)的知识。

  • BluetoothServerSocket——服务端(监听端、监听器、接受请求的一端)

    • Accept()——阻塞宿主线程,直至收到客户端请求。返回BluetoothSocket对象。由于这个
    • Accept(int timeout)——阻塞宿主线程,直至收到客户端请求或等待时间超过timeout。返回BluetoothSocket对象。
    • Close()——关闭BluetoothServerSocket监听器。

  可以看到,Accept方法是一个阻塞方法,所以在进行开发的时候,一般都需要用到多线程的知识。JAVA的多线程知识。

  • BluetoothSocket——客户端(请求端)

    • Close()——关闭BluetoothSocket请求端。
    • Connect()——主动向服务端(监听端)发起连接请求。

可使用BluetoothAdapter类的listenUsingRfcommWithServiceRecord方法来新建一个ServerSocket。

  可以使用web上的任何一款UUID产生器为你的程序获取一个UUID,然后使用fromString(String)初始化一个UUID。

  使用ServerSocket实例的accept方法进行监听,当监听到带有我们初始化的UUID参数的连接请求后作出响应,连接成功后返回一个BluetoothSocket对象。连接完成后,调用close方法关闭该Socket监听。

使用BluetoothDevice的实例的createRfcommSocketToServiceRecord方法来创建一个BluetoothSocket实例。

  传入我们服务端的UUID值。

  然后使用BluetoothSocket实例的Connect方法对Server端进行连接请求,当连接成功后,Client端和Server端的传输通道就被打开。

参考链接:

Android中连接蓝牙设备时遇到createRfcommSocketToServiceRecord的UUID问题和BluetoothSocket的connect失败

http://www.cnblogs.com/cxcco/archive/2012/01/15/2322783.html

时间: 2024-10-13 20:18:58

Android 读取蓝牙设备信息开发的相关文章

android读取apk中已经存在的数据库信息

在android数据库编程方面,大家有没有遇到过,我要从指定位置的已经存在的数据库来进行操作的问题.之前我尝试了很多方法都没有成功,后来找到了解决的方法.   下面说明下这段代码的意思,第一步先判断在指定的路劲是否存在,不存在就创建设计素材大全.第二步将android的资源下的数据库复制到指定路径下面.第三步就是根据指定路径打开或者创建数据库,然后得到操作数据库的对象,得到操作数据库的对象了,自然就可以对数据库中的表进行增删改查等操作了. 1. [代码]android程序读取项目中已经存在的数据

Android 低功耗蓝牙BLE 开发注意事项

基本概念和问题 1.蓝牙设计范式? 当手机通过扫描低功耗蓝牙设备并连接上后,手机与蓝牙设备构成了客户端-服务端架构.手机通过连接蓝牙设备,可以读取蓝牙设备上的信息.手机就是客户端,蓝牙设备是服务端. 手机做为客户端可以连接多个蓝牙设备,所以手机又可以叫中心设备(Central),蓝牙设备叫外围设备(Peripheral). 还有另外一个称谓:手机叫主设备(Master),蓝牙设备叫从设备(Slave). Android4.3 开始支持低功耗蓝牙,此版本只支持单模式:同时只能工作在中心设备模式或者

【小功能2】android获取手机信息(号码,内存,CPU,分辨率,MAC,IP,SD卡,IMEI,经纬度,信号强度等等)

为了实现一个功能,需要搜集手机信息,自己先在网上找了相关信息进行了汇总,主要是汇集手机的信息,一般想要的信息在手机设置->关于手机->状态消息里面包含了手机的各种信息,下面的代码中也主要显示了那些信息,但是源码的方法我还没有看,先把总结的贴出来.先上图(太多就截取几个).  上代码啦,太多了,就写主要代码了. // 获取Android手机中SD卡存储信息 获取剩余空间 public void getSDCardInfo() { // 在manifest.xml文件中要添加 /* * <u

Android研究之游戏开发摄像头更新

 游戏中摄像头的原理介绍        在游戏开发中更新摄像头的位置可以决定屏幕显示的内容,尤其是RPG类游戏摄像头有着非常重要的作用,我举一个例子 有时候我们在玩RPG游戏的时候进入一个新的场景 触发一段脚本后 发现镜头开始向上移动 根据镜头移动玩家可以大概浏览一下这个场景有什么东西 ,触发什么样的剧情.这个实现的方式就是游戏摄像头原理.上章学习了Android游戏开发地图编辑器有需要的可以看下. 如图所示:首先摄像头显示的区域也是手机屏幕显示的区域 如果需要更改摄像头的位置  其实是更改

【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面

大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要想实现应用程序只启动一次引导界面这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单,下面来详细介绍一下这个类的使用方法 1.SharedPreferences的详细介绍和用法 其实在 20.游戏开发基础(游戏数据存储)中已经有过介绍了,为了文章的完整还是再介绍一遍. 做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库

【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

[Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界面开发专题的一个终结了吧,个人觉得大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要是在今后的开发中遇到了更好玩,更有趣的引导界面,博主也会在这里及时的跟大家分享,今天的内容主要是教大家的应用程序只有在第一次启动的时候显示引导界面,以后在启动程序的时候就不再显示了

Android研究之游戏开发多线程详解

 游戏开发与软件开发多线程的重要性       如果程序主线程被阻塞超过5秒,系统会提示"应用程序无响应" 这就是ANR . ANR的全称是Application Not Responding,使用多线程可以避免ANR.但是这里要注意一下不要为了避免ANR而过多的使用多线程,除非万不得已的情况. 比如访问网络服务端返回的过慢.数据过多导致滑动屏幕不流畅.或者I/O读取过大的资源等等.这里可以开启一个新线程来处理这些耗时的操作. 如果过多使用多线程会出现数据同步的问题须要程序员去处理

Eclipse+ADT+Android SDK 搭建安卓开发环境

要求 必备知识 windows 7 基本操作. 运行环境 windows 7 下载地址 环境下载 最近开接触Android(安卓)嵌入式开发,首要问题是搭建Andoid开发环境,由于本人用的是windows7的笔记本,也就只能到Windows中搭建Android 开发环境了! 就搭建环境都花了比较长的时间, 在各种版本之间折腾了比较久的时间, 装好后SDK包更新又是一个比较大的麻烦(天朝的网络大家懂的--).下面把我的安装过程和经验分享个大家!! 安装JDK 这里可以参考我之前写的一篇关于安装J

第二章 Android系统与嵌入式开发

第二章 Android系统与嵌入式开发 第二章首先要先了解Android和嵌入式Lnux系统有什么区别和联系,嵌入式Linux系统是在嵌入式设备中运行Linux系统:Android系统是在嵌入式设备中运行Android系统. 其区别就是Android系统和Linux系统的区别.Android系统的底层是Linux的内核,上面跑的是Android的java虚拟机.Android系统的UI做的比Lnux好很多. 首先我们应该先了解一下什么是嵌入式,对于嵌入式来说,它是一种“完全嵌入受控器件内部,为特